Merge "Add KEY_VVM_PREFETCH_BOOLEAN to CarrierConfigManager"
diff --git a/Android.mk b/Android.mk
index e94bebb..8daa1aa 100644
--- a/Android.mk
+++ b/Android.mk
@@ -206,6 +206,7 @@
 	core/java/android/nfc/INfcAdapterExtras.aidl \
 	core/java/android/nfc/INfcTag.aidl \
 	core/java/android/nfc/INfcCardEmulation.aidl \
+	core/java/android/nfc/INfcFCardEmulation.aidl \
 	core/java/android/nfc/INfcUnlockHandler.aidl \
 	core/java/android/os/IBatteryPropertiesListener.aidl \
 	core/java/android/os/IBatteryPropertiesRegistrar.aidl \
@@ -287,6 +288,7 @@
 	core/java/com/android/internal/app/IBatteryStats.aidl \
 	core/java/com/android/internal/app/IEphemeralResolver.aidl \
 	core/java/com/android/internal/app/IProcessStats.aidl \
+	core/java/com/android/internal/app/ISoundTriggerService.aidl \
 	core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl \
 	core/java/com/android/internal/app/IVoiceInteractionSessionShowCallback.aidl \
 	core/java/com/android/internal/app/IVoiceInteractor.aidl \
@@ -416,7 +418,6 @@
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
-	wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl \
 	wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl \
 	wifi/java/android/net/wifi/nan/IWifiNanManager.aidl \
 	wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl \
@@ -429,6 +430,14 @@
 	core/java/android/service/quicksettings/IQSService.aidl \
 	core/java/android/service/quicksettings/IQSTileService.aidl \
 
+# The following are native binders that need to go with the native component
+# at system/update_engine/binder_bindings/. Use relative path to refer to them.
+LOCAL_SRC_FILES += \
+	../../system/update_engine/binder_bindings/android/os/IUpdateEngine.aidl \
+	../../system/update_engine/binder_bindings/android/os/IUpdateEngineCallback.aidl \
+
+LOCAL_AIDL_INCLUDES += system/update_engine/binder_bindings
+
 # FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
 LOCAL_AIDL_INCLUDES += \
       $(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
@@ -441,6 +450,7 @@
 
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core-oj core-libart conscrypt okhttp core-junit bouncycastle ext
+LOCAL_STATIC_JAVA_LIBRARIES := framework-protos
 
 LOCAL_MODULE := framework
 
diff --git a/api/current.txt b/api/current.txt
index e281969..0b371e8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -67,7 +67,7 @@
     field public static final java.lang.String DUMP = "android.permission.DUMP";
     field public static final java.lang.String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
     field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
-    field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
+    field public static final deprecated java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
     field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
     field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
     field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
@@ -1183,6 +1183,7 @@
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsAssist = 16844016; // 0x10104f0
     field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
+    field public static final int supportsLocalInteraction = 16844048; // 0x1010510
     field public static final int supportsPictureInPicture = 16844024; // 0x10104f8
     field public static final int supportsRtl = 16843695; // 0x10103af
     field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
@@ -3436,6 +3437,7 @@
     method public boolean isDestroyed();
     method public boolean isFinishing();
     method public boolean isImmersive();
+    method public boolean isLocalVoiceInteractionSupported();
     method public boolean isTaskRoot();
     method public boolean isVoiceInteraction();
     method public boolean isVoiceInteractionRoot();
@@ -3477,6 +3479,8 @@
     method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
     method public boolean onKeyShortcut(int, android.view.KeyEvent);
     method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public void onLocalVoiceInteractionStarted();
+    method public void onLocalVoiceInteractionStopped();
     method public void onLowMemory();
     method public boolean onMenuItemSelected(int, android.view.MenuItem);
     method public boolean onMenuOpened(int, android.view.Menu);
@@ -3591,12 +3595,14 @@
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSenderFromChild(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSenderFromChild(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void startLocalVoiceInteraction(android.os.Bundle);
     method public void startLockTask();
     method public deprecated void startManagingCursor(android.database.Cursor);
     method public boolean startNextMatchingActivity(android.content.Intent);
     method public boolean startNextMatchingActivity(android.content.Intent, android.os.Bundle);
     method public void startPostponedEnterTransition();
     method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
+    method public void stopLocalVoiceInteraction();
     method public void stopLockTask();
     method public deprecated void stopManagingCursor(android.database.Cursor);
     method public void takeKeyEvents(boolean);
@@ -3670,9 +3676,6 @@
     method public void startActivity(android.content.Context, android.content.Intent, android.os.Bundle);
   }
 
-  public static abstract class ActivityManager.BugreportMode implements java.lang.annotation.Annotation {
-  }
-
   public static class ActivityManager.MemoryInfo implements android.os.Parcelable {
     ctor public ActivityManager.MemoryInfo();
     method public int describeContents();
@@ -5686,10 +5689,13 @@
     method public android.graphics.drawable.Drawable peekFastDrawable();
     method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
     method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
-    method public void setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean, int) throws java.io.IOException;
     method public void setResource(int) throws java.io.IOException;
+    method public int setResource(int, int) throws java.io.IOException;
     method public void setStream(java.io.InputStream) throws java.io.IOException;
-    method public void setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setStream(java.io.InputStream, android.graphics.Rect, boolean, int) throws java.io.IOException;
     method public void setWallpaperOffsetSteps(float, float);
     method public void setWallpaperOffsets(android.os.IBinder, float, float);
     method public void suggestDesiredDimensions(int, int);
@@ -5700,6 +5706,8 @@
     field public static final java.lang.String COMMAND_SECONDARY_TAP = "android.wallpaper.secondaryTap";
     field public static final java.lang.String COMMAND_TAP = "android.wallpaper.tap";
     field public static final java.lang.String EXTRA_LIVE_WALLPAPER_COMPONENT = "android.service.wallpaper.extra.LIVE_WALLPAPER_COMPONENT";
+    field public static final int FLAG_SET_LOCK = 2; // 0x2
+    field public static final int FLAG_SET_SYSTEM = 1; // 0x1
     field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
   }
 
@@ -5772,9 +5780,6 @@
     field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
   }
 
-  public static abstract class DeviceAdminReceiver.BugreportFailureCode implements java.lang.annotation.Annotation {
-  }
-
   public class DevicePolicyManager {
     method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
     method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5785,6 +5790,7 @@
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
     method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
     method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+    method public android.os.UserHandle createAndManageUser(android.content.ComponentName, java.lang.String, android.content.ComponentName, android.os.PersistableBundle, int);
     method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
     method public void enableSystemApp(android.content.ComponentName, java.lang.String);
     method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
@@ -5977,6 +5983,7 @@
     field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
     field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
     field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
+    field public static final int SKIP_SETUP_WIZARD = 1; // 0x1
     field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
     field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
   }
@@ -6098,6 +6105,7 @@
     method public void onCreate();
     method public void onDestroy();
     method public void onFullBackup(android.app.backup.FullBackupDataOutput) throws java.io.IOException;
+    method public void onQuotaExceeded(long, long);
     method public abstract void onRestore(android.app.backup.BackupDataInput, int, android.os.ParcelFileDescriptor) throws java.io.IOException;
     method public void onRestoreFile(android.os.ParcelFileDescriptor, long, java.io.File, int, long, long) throws java.io.IOException;
     method public void onRestoreFinished();
@@ -6186,6 +6194,7 @@
     method public long getMinLatencyMillis();
     method public int getNetworkType();
     method public android.content.ComponentName getService();
+    method public android.app.job.JobInfo.TriggerContentUri[] getTriggerContentUris();
     method public boolean isPeriodic();
     method public boolean isPersisted();
     method public boolean isRequireCharging();
@@ -6205,6 +6214,7 @@
 
   public static final class JobInfo.Builder {
     ctor public JobInfo.Builder(int, android.content.ComponentName);
+    method public android.app.job.JobInfo.Builder addTriggerContentUri(android.app.job.JobInfo.TriggerContentUri);
     method public android.app.job.JobInfo build();
     method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int);
     method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle);
@@ -6218,10 +6228,22 @@
     method public android.app.job.JobInfo.Builder setRequiresDeviceIdle(boolean);
   }
 
+  public static final class JobInfo.TriggerContentUri implements android.os.Parcelable {
+    ctor public JobInfo.TriggerContentUri(android.net.Uri, int);
+    method public int describeContents();
+    method public int getFlags();
+    method public android.net.Uri getUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.job.JobInfo.TriggerContentUri> CREATOR;
+    field public static final int FLAG_NOTIFY_FOR_DESCENDANTS = 1; // 0x1
+  }
+
   public class JobParameters implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.PersistableBundle getExtras();
     method public int getJobId();
+    method public java.lang.String[] getTriggeredContentAuthorities();
+    method public android.net.Uri[] getTriggeredContentUris();
     method public boolean isOverrideDeadlineExpired();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.job.JobParameters> CREATOR;
@@ -8015,6 +8037,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
+    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
@@ -8368,7 +8391,6 @@
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
-    field public static final java.lang.String ACTION_AVAILABILITY_CHANGED = "android.intent.action.AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
     field public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
@@ -8452,6 +8474,7 @@
     field public static final java.lang.String ACTION_PROCESS_TEXT = "android.intent.action.PROCESS_TEXT";
     field public static final java.lang.String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED";
     field public static final java.lang.String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK";
+    field public static final java.lang.String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
     field public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT";
     field public static final java.lang.String ACTION_RUN = "android.intent.action.RUN";
     field public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
@@ -8545,6 +8568,7 @@
     field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
     field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
     field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+    field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
     field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
     field public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT";
@@ -9641,6 +9665,7 @@
     field public static final java.lang.String FEATURE_MIDI = "android.software.midi";
     field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
     field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
+    field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef";
     field public static final java.lang.String FEATURE_OPENGLES_EXTENSION_PACK = "android.hardware.opengles.aep";
     field public static final java.lang.String FEATURE_PICTURE_IN_PICTURE = "android.software.picture_in_picture";
     field public static final java.lang.String FEATURE_PRINTING = "android.software.print";
@@ -10085,7 +10110,6 @@
     method public java.lang.String getQuantityString(int, int, java.lang.Object...) throws android.content.res.Resources.NotFoundException;
     method public java.lang.String getQuantityString(int, int) throws android.content.res.Resources.NotFoundException;
     method public java.lang.CharSequence getQuantityText(int, int) throws android.content.res.Resources.NotFoundException;
-    method public java.util.Locale getResolvedLocale();
     method public java.lang.String getResourceEntryName(int) throws android.content.res.Resources.NotFoundException;
     method public java.lang.String getResourceName(int) throws android.content.res.Resources.NotFoundException;
     method public java.lang.String getResourcePackageName(int) throws android.content.res.Resources.NotFoundException;
@@ -13352,6 +13376,7 @@
     field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD = "android.sensor.magnetic_field";
     field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED = "android.sensor.magnetic_field_uncalibrated";
     field public static final deprecated java.lang.String STRING_TYPE_ORIENTATION = "android.sensor.orientation";
+    field public static final java.lang.String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof";
     field public static final java.lang.String STRING_TYPE_PRESSURE = "android.sensor.pressure";
     field public static final java.lang.String STRING_TYPE_PROXIMITY = "android.sensor.proximity";
     field public static final java.lang.String STRING_TYPE_RELATIVE_HUMIDITY = "android.sensor.relative_humidity";
@@ -13374,6 +13399,7 @@
     field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2
     field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe
     field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3
+    field public static final int TYPE_POSE_6DOF = 28; // 0x1c
     field public static final int TYPE_PRESSURE = 6; // 0x6
     field public static final int TYPE_PROXIMITY = 8; // 0x8
     field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
@@ -13575,6 +13601,7 @@
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AF;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AWB;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>> CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> DEPTH_DEPTH_IS_EXCLUSIVE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> EDGE_AVAILABLE_EDGE_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> FLASH_INFO_AVAILABLE;
@@ -13654,9 +13681,11 @@
     method public abstract void close();
     method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
     method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void createCaptureSessionByOutputConfiguration(java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
     method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void createReprocessableCaptureSessionWithConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract java.lang.String getId();
     field public static final int TEMPLATE_MANUAL = 6; // 0x6
     field public static final int TEMPLATE_PREVIEW = 1; // 0x1
@@ -13813,6 +13842,7 @@
     field public static final int HOT_PIXEL_MODE_FAST = 1; // 0x1
     field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2
     field public static final int HOT_PIXEL_MODE_OFF = 0; // 0x0
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3; // 0x3
     field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1
     field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; // 0x2
     field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0
@@ -13934,6 +13964,7 @@
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_SCENE_MODE;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
     field public static final android.os.Parcelable.Creator<android.hardware.camera2.CaptureRequest> CREATOR;
@@ -14012,6 +14043,7 @@
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_SCENE_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> EDGE_MODE;
@@ -14153,6 +14185,17 @@
     field public static final int METERING_WEIGHT_MIN = 0; // 0x0
   }
 
+  public final class OutputConfiguration implements android.os.Parcelable {
+    ctor public OutputConfiguration(android.view.Surface);
+    method public int describeContents();
+    method public android.view.Surface getSurface();
+    method public int getSurfaceSetId();
+    method public void setSurfaceSetId(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
+    field public static final int SURFACE_SET_ID_INVALID = -1; // 0xffffffff
+  }
+
   public final class RggbChannelVector {
     ctor public RggbChannelVector(float, float, float, float);
     method public void copyTo(float[], int);
@@ -20040,6 +20083,7 @@
     field public static final deprecated int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00
     field public static final deprecated int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
     field public static final java.lang.String FEATURE_AdaptivePlayback = "adaptive-playback";
+    field public static final java.lang.String FEATURE_IntraRefresh = "intra-refresh";
     field public static final java.lang.String FEATURE_SecurePlayback = "secure-playback";
     field public static final java.lang.String FEATURE_TunneledPlayback = "tunneled-playback";
     field public int[] colorFormats;
@@ -20082,6 +20126,21 @@
     field public static final int AVCProfileHigh422 = 32; // 0x20
     field public static final int AVCProfileHigh444 = 64; // 0x40
     field public static final int AVCProfileMain = 2; // 0x2
+    field public static final int DolbyVisionLevelFhd24 = 4; // 0x4
+    field public static final int DolbyVisionLevelFhd30 = 8; // 0x8
+    field public static final int DolbyVisionLevelFhd60 = 16; // 0x10
+    field public static final int DolbyVisionLevelHd24 = 1; // 0x1
+    field public static final int DolbyVisionLevelHd30 = 2; // 0x2
+    field public static final int DolbyVisionLevelUhd24 = 32; // 0x20
+    field public static final int DolbyVisionLevelUhd30 = 64; // 0x40
+    field public static final int DolbyVisionLevelUhd48 = 128; // 0x80
+    field public static final int DolbyVisionLevelUhd60 = 256; // 0x100
+    field public static final int DolbyVisionProfileDvavDen = 2; // 0x2
+    field public static final int DolbyVisionProfileDvavDer = 1; // 0x1
+    field public static final int DolbyVisionProfileDvheDen = 4; // 0x4
+    field public static final int DolbyVisionProfileDvheDer = 3; // 0x3
+    field public static final int DolbyVisionProfileDvheDtr = 5; // 0x5
+    field public static final int DolbyVisionProfileDvheStn = 6; // 0x6
     field public static final int H263Level10 = 1; // 0x1
     field public static final int H263Level20 = 2; // 0x2
     field public static final int H263Level30 = 4; // 0x4
@@ -20166,6 +20225,24 @@
     field public static final int VP8Level_Version2 = 4; // 0x4
     field public static final int VP8Level_Version3 = 8; // 0x8
     field public static final int VP8ProfileMain = 1; // 0x1
+    field public static final int VP9Level1 = 0; // 0x0
+    field public static final int VP9Level11 = 1; // 0x1
+    field public static final int VP9Level2 = 2; // 0x2
+    field public static final int VP9Level21 = 4; // 0x4
+    field public static final int VP9Level3 = 8; // 0x8
+    field public static final int VP9Level31 = 16; // 0x10
+    field public static final int VP9Level4 = 32; // 0x20
+    field public static final int VP9Level41 = 64; // 0x40
+    field public static final int VP9Level5 = 128; // 0x80
+    field public static final int VP9Level51 = 256; // 0x100
+    field public static final int VP9Level52 = 512; // 0x200
+    field public static final int VP9Level6 = 1024; // 0x400
+    field public static final int VP9Level61 = 2048; // 0x800
+    field public static final int VP9Level62 = 4096; // 0x1000
+    field public static final int VP9Profile0 = 0; // 0x0
+    field public static final int VP9Profile1 = 1; // 0x1
+    field public static final int VP9Profile2 = 2; // 0x2
+    field public static final int VP9Profile3 = 3; // 0x3
     field public int level;
     field public int profile;
   }
@@ -20413,6 +20490,7 @@
     field public static final java.lang.String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
     field public static final java.lang.String KEY_FRAME_RATE = "frame-rate";
     field public static final java.lang.String KEY_HEIGHT = "height";
+    field public static final java.lang.String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period";
     field public static final java.lang.String KEY_IS_ADTS = "is-adts";
     field public static final java.lang.String KEY_IS_AUTOSELECT = "is-autoselect";
     field public static final java.lang.String KEY_IS_DEFAULT = "is-default";
@@ -20734,9 +20812,11 @@
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.view.Surface getSurface();
+    method public void pause() throws java.lang.IllegalStateException;
     method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
     method public void release();
     method public void reset();
+    method public void resume() throws java.lang.IllegalStateException;
     method public void setAudioChannels(int);
     method public void setAudioEncoder(int) throws java.lang.IllegalStateException;
     method public void setAudioEncodingBitRate(int);
@@ -20816,6 +20896,7 @@
     field public static final int DEFAULT = 0; // 0x0
     field public static final int H263 = 1; // 0x1
     field public static final int H264 = 2; // 0x2
+    field public static final int HEVC = 5; // 0x5
     field public static final int MPEG_4_SP = 3; // 0x3
     field public static final int VP8 = 4; // 0x4
   }
@@ -21704,7 +21785,11 @@
     method public android.media.session.MediaSession.Token getSessionToken();
     method public boolean isConnected();
     method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
+    method public void subscribe(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void unsubscribe(java.lang.String);
+    method public void unsubscribe(java.lang.String, android.os.Bundle);
+    field public static final java.lang.String EXTRA_PAGE = "android.media.browse.extra.PAGE";
+    field public static final java.lang.String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
   }
 
   public static class MediaBrowser.ConnectionCallback {
@@ -21737,7 +21822,9 @@
   public static abstract class MediaBrowser.SubscriptionCallback {
     ctor public MediaBrowser.SubscriptionCallback();
     method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
+    method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>, android.os.Bundle);
     method public void onError(java.lang.String);
+    method public void onError(java.lang.String, android.os.Bundle);
   }
 
 }
@@ -22175,6 +22262,7 @@
     method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
     method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
     method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+    method public static final android.net.Uri buildRecordedProgramUri(long);
     field public static final java.lang.String AUTHORITY = "android.media.tv";
   }
 
@@ -22311,13 +22399,49 @@
     field public static final java.lang.String TRAVEL = "TRAVEL";
   }
 
+  public static final class TvContract.RecordedPrograms implements android.media.tv.TvContract.BaseTvColumns {
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    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_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";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+    field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
+    field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
+    field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
+    field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_NUMBER = "season_number";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
+    field public static final android.net.Uri CONTENT_URI;
+  }
+
   public final class TvInputInfo implements android.os.Parcelable {
+    method public boolean canRecord();
     method public android.content.Intent createSettingsIntent();
     method public android.content.Intent createSetupIntent();
     method public int describeContents();
     method public java.lang.String getId();
     method public java.lang.String getParentId();
     method public android.content.pm.ServiceInfo getServiceInfo();
+    method public int getTunerCount();
     method public int getType();
     method public boolean isPassthroughInput();
     method public android.graphics.drawable.Drawable loadIcon(android.content.Context);
@@ -22337,6 +22461,13 @@
     field public static final int TYPE_VGA = 1005; // 0x3ed
   }
 
+  public static final class TvInputInfo.Builder {
+    ctor public TvInputInfo.Builder(android.content.Context, java.lang.Class<?>);
+    method public android.media.tv.TvInputInfo build() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public android.media.tv.TvInputInfo.Builder setCanRecord(boolean);
+    method public android.media.tv.TvInputInfo.Builder setTunerCount(int);
+  }
+
   public final class TvInputManager {
     method public int getInputState(java.lang.String);
     method public android.media.tv.TvInputInfo getTvInputInfo(java.lang.String);
@@ -22352,6 +22483,10 @@
     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_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
     field public static final int TIME_SHIFT_STATUS_UNAVAILABLE = 2; // 0x2
@@ -22369,12 +22504,15 @@
     method public void onInputAdded(java.lang.String);
     method public void onInputRemoved(java.lang.String);
     method public void onInputStateChanged(java.lang.String, int);
+    method public void onTvInputInfoChanged(java.lang.String, android.media.tv.TvInputInfo);
   }
 
   public abstract class TvInputService extends android.app.Service {
     ctor public TvInputService();
     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 final void setTvInputInfo(java.lang.String, 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";
   }
@@ -22387,6 +22525,18 @@
     method public final boolean onSetSurface(android.view.Surface);
   }
 
+  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 abstract void onStopRecording();
+  }
+
   public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
     ctor public TvInputService.Session(android.content.Context);
     method public void layoutSurface(int, int, int, int);
@@ -22414,6 +22564,7 @@
     method public long onTimeShiftGetCurrentPosition();
     method public long onTimeShiftGetStartPosition();
     method public void onTimeShiftPause();
+    method public void onTimeShiftPlay(android.net.Uri);
     method public void onTimeShiftResume();
     method public void onTimeShiftSeekTo(long);
     method public void onTimeShiftSetPlaybackParams(android.media.PlaybackParams);
@@ -22424,6 +22575,23 @@
     method public void setOverlayViewEnabled(boolean);
   }
 
+  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 stopRecording();
+  }
+
+  public class TvRecordingClient.RecordingCallback {
+    ctor public TvRecordingClient.RecordingCallback();
+    method public void onConnected();
+    method public void onDisconnected();
+    method public void onError(int);
+    method public void onRecordingStarted();
+    method public void onRecordingStopped(android.net.Uri);
+  }
+
   public final class TvTrackInfo implements android.os.Parcelable {
     method public int describeContents();
     method public final int getAudioChannelCount();
@@ -22475,6 +22643,7 @@
     method public void setStreamVolume(float);
     method public void setTimeShiftPositionCallback(android.media.tv.TvView.TimeShiftPositionCallback);
     method public void timeShiftPause();
+    method public void timeShiftPlay(java.lang.String, android.net.Uri);
     method public void timeShiftResume();
     method public void timeShiftSeekTo(long);
     method public void timeShiftSetPlaybackParams(android.media.PlaybackParams);
@@ -22550,6 +22719,7 @@
     field public static final int FORMAT_AUDIBLE = 47364; // 0xb904
     field public static final int FORMAT_AVI = 12298; // 0x300a
     field public static final int FORMAT_BMP = 14340; // 0x3804
+    field public static final int FORMAT_DEFINED = 14336; // 0x3800
     field public static final int FORMAT_DNG = 14353; // 0x3811
     field public static final int FORMAT_DPOF = 12294; // 0x3006
     field public static final int FORMAT_EXECUTABLE = 12291; // 0x3003
@@ -22655,6 +22825,7 @@
   }
 
   public class MtpDeviceInfo {
+    method public final int[] getEventsSupported();
     method public final java.lang.String getManufacturer();
     method public final java.lang.String getModel();
     method public final int[] getOperationsSupported();
@@ -22825,9 +22996,6 @@
     method public abstract void onNetworkActive();
   }
 
-  public static abstract class ConnectivityManager.RestrictBackgroundStatus implements java.lang.annotation.Annotation {
-  }
-
   public class Credentials {
     ctor public Credentials(int, int, int);
     method public int getGid();
@@ -23841,6 +24009,7 @@
     method public java.lang.String getAltSubjectMatch();
     method public java.lang.String getAnonymousIdentity();
     method public java.security.cert.X509Certificate getCaCertificate();
+    method public java.security.cert.X509Certificate[] getCaCertificates();
     method public java.security.cert.X509Certificate getClientCertificate();
     method public java.lang.String getDomainSuffixMatch();
     method public int getEapMethod();
@@ -23853,6 +24022,7 @@
     method public void setAltSubjectMatch(java.lang.String);
     method public void setAnonymousIdentity(java.lang.String);
     method public void setCaCertificate(java.security.cert.X509Certificate);
+    method public void setCaCertificates(java.security.cert.X509Certificate[]);
     method public void setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate);
     method public void setDomainSuffixMatch(java.lang.String);
     method public void setEapMethod(int);
@@ -24382,6 +24552,28 @@
     field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
   }
 
+  public abstract class HostNfcFService extends android.app.Service {
+    ctor public HostNfcFService();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract void onDeactivated(int);
+    method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle);
+    method public final void sendResponsePacket(byte[]);
+    field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
+    field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
+    field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service";
+  }
+
+  public final class NfcFCardEmulation {
+    method public boolean disableNfcFForegroundService(android.app.Activity);
+    method public boolean enableNfcFForegroundService(android.app.Activity, android.content.ComponentName);
+    method public static synchronized android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter);
+    method public java.lang.String getNfcid2ForService(android.content.ComponentName);
+    method public java.lang.String getSystemCodeForService(android.content.ComponentName);
+    method public boolean registerSystemCodeForService(android.content.ComponentName, java.lang.String);
+    method public boolean removeSystemCodeForService(android.content.ComponentName);
+    method public boolean setNfcid2ForService(android.content.ComponentName, java.lang.String);
+  }
+
   public abstract class OffHostApduService extends android.app.Service {
     ctor public OffHostApduService();
     method public abstract android.os.IBinder onBind(android.content.Intent);
@@ -27738,6 +27930,14 @@
     method public final synchronized android.os.CountDownTimer start();
   }
 
+  public final class CpuUsageInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getActive();
+    method public long getTotal();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.os.CpuUsageInfo> CREATOR;
+  }
+
   public class DeadObjectException extends android.os.RemoteException {
     ctor public DeadObjectException();
     ctor public DeadObjectException(java.lang.String);
@@ -27990,6 +28190,18 @@
     method public boolean quitSafely();
   }
 
+  public class HardwarePropertiesManager {
+    method public android.os.CpuUsageInfo[] getCpuUsages();
+    method public float[] getDeviceTemperatures(int);
+    method public float[] getFanSpeeds();
+    field public static final int DEVICE_TEMPERATURE_BATTERY = 2; // 0x2
+    field public static final int DEVICE_TEMPERATURE_CPU = 0; // 0x0
+    field public static final int DEVICE_TEMPERATURE_GPU = 1; // 0x1
+  }
+
+  public static abstract class HardwarePropertiesManager.DeviceTemperatureType implements java.lang.annotation.Annotation {
+  }
+
   public abstract interface IBinder {
     method public abstract void dump(java.io.FileDescriptor, java.lang.String[]) throws android.os.RemoteException;
     method public abstract void dumpAsync(java.io.FileDescriptor, java.lang.String[]) throws android.os.RemoteException;
@@ -28359,6 +28571,7 @@
     field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1
     field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
     field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
+    field public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 256; // 0x100
   }
 
   public final class PowerManager.WakeLock {
@@ -30713,10 +30926,14 @@
 
   public static final class ContactsContract.Intents {
     ctor public ContactsContract.Intents();
+    field public static final java.lang.String ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS = "android.provider.action.VOICE_SEND_MESSAGE_TO_CONTACTS";
     field public static final java.lang.String ATTACH_IMAGE = "com.android.contacts.action.ATTACH_IMAGE";
     field public static final java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
     field public static final java.lang.String EXTRA_CREATE_DESCRIPTION = "com.android.contacts.action.CREATE_DESCRIPTION";
     field public static final java.lang.String EXTRA_FORCE_CREATE = "com.android.contacts.action.FORCE_CREATE";
+    field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
+    field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_NAME = "android.provider.extra.RECIPIENT_CONTACT_NAME";
+    field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_URI = "android.provider.extra.RECIPIENT_CONTACT_URI";
     field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
     field public static final java.lang.String SEARCH_SUGGESTION_CLICKED = "android.provider.Contacts.SEARCH_SUGGESTION_CLICKED";
     field public static final java.lang.String SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED = "android.provider.Contacts.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED";
@@ -30962,6 +31179,7 @@
     method public static android.net.Uri buildRootsUri(java.lang.String);
     method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String);
     method public static android.net.Uri buildTreeDocumentUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri copyDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri);
     method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
@@ -30970,6 +31188,7 @@
     method public static java.lang.String getSearchDocumentsQuery(android.net.Uri);
     method public static java.lang.String getTreeDocumentId(android.net.Uri);
     method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
+    method public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri);
     method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
     field public static final java.lang.String EXTRA_ERROR = "error";
     field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
@@ -32796,6 +33015,7 @@
     method public void getVarV(int, android.renderscript.FieldPacker);
     method protected void invoke(int);
     method protected void invoke(int, android.renderscript.FieldPacker);
+    method protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void setTimeZone(java.lang.String);
     method public void setVar(int, float);
     method public void setVar(int, double);
@@ -33647,9 +33867,11 @@
     method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public android.media.session.MediaSession.Token getSessionToken();
     method public void notifyChildrenChanged(java.lang.String);
+    method public void notifyChildrenChanged(java.lang.String, android.os.Bundle);
     method public android.os.IBinder onBind(android.content.Intent);
     method public abstract android.service.media.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
     method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
+    method public void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>, android.os.Bundle);
     method public void onLoadItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>);
     method public void setSessionToken(android.media.session.MediaSession.Token);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
@@ -33734,6 +33956,7 @@
     field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb
     field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
     field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
+    field public static final int REASON_PACKAGE_SUSPENDED = 15; // 0xf
     field public static final int REASON_TOPIC_BANNED = 14; // 0xe
     field public static final int REASON_USER_STOPPED = 6; // 0x6
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
@@ -33997,6 +34220,7 @@
     method public void setTheme(int);
     method public void show(android.os.Bundle, int);
     method public void startVoiceActivity(android.content.Intent);
+    field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10
     field public static final int SHOW_SOURCE_APPLICATION = 8; // 0x8
     field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4
     field public static final int SHOW_WITH_ASSIST = 1; // 0x1
@@ -34358,6 +34582,8 @@
 
   public abstract class UtteranceProgressListener {
     ctor public UtteranceProgressListener();
+    method public void onAudioAvailable(java.lang.String, byte[]);
+    method public void onBeginSynthesis(java.lang.String, int, int, int);
     method public abstract void onDone(java.lang.String);
     method public abstract deprecated void onError(java.lang.String);
     method public void onError(java.lang.String, int);
@@ -35105,6 +35331,7 @@
     method public static boolean hasProperty(int, int);
     method public boolean hasProperty(int);
     method public static java.lang.String propertiesToString(int);
+    field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
@@ -35245,6 +35472,7 @@
     method public final void setVideoProvider(android.telecom.Connection.VideoProvider);
     method public final void setVideoState(int);
     method public static java.lang.String stateToString(int);
+    field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
@@ -35624,6 +35852,7 @@
     field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
+    field public static final java.lang.String ACTION_SHOW_MISSED_CALLS_NOTIFICATION = "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
     field public static final java.lang.String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS";
     field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
     field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
@@ -35634,6 +35863,8 @@
     field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
     field public static final java.lang.String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
+    field public static final java.lang.String EXTRA_NOTIFICATION_COUNT = "android.telecom.extra.NOTIFICATION_COUNT";
+    field public static final java.lang.String EXTRA_NOTIFICATION_PHONE_NUMBER = "android.telecom.extra.NOTIFICATION_PHONE_NUMBER";
     field public static final java.lang.String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
     field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
     field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
@@ -35809,6 +36040,8 @@
 
   public final class CellIdentityGsm implements android.os.Parcelable {
     method public int describeContents();
+    method public int getArfcn();
+    method public int getBsic();
     method public int getCid();
     method public int getLac();
     method public int getMcc();
@@ -35821,6 +36054,7 @@
   public final class CellIdentityLte implements android.os.Parcelable {
     method public int describeContents();
     method public int getCi();
+    method public int getEarfcn();
     method public int getMcc();
     method public int getMnc();
     method public int getPci();
@@ -35836,6 +36070,7 @@
     method public int getMcc();
     method public int getMnc();
     method public int getPsc();
+    method public int getUarfcn();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityWcdma> CREATOR;
   }
@@ -36257,10 +36492,15 @@
     method public int getActiveSubscriptionInfoCountMax();
     method public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int);
     method public java.util.List<android.telephony.SubscriptionInfo> getActiveSubscriptionInfoList();
+    method public static int getDefaultDataSubscriptionId();
+    method public static int getDefaultSmsSubscriptionId();
+    method public static int getDefaultSubscriptionId();
+    method public static int getDefaultVoiceSubscriptionId();
     method public boolean isNetworkRoaming(int);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
     field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
     field public static final int DATA_ROAMING_ENABLE = 1; // 0x1
+    field public static final int INVALID_SUBSCRIPTION_ID = -1; // 0xffffffff
   }
 
   public static class SubscriptionManager.OnSubscriptionsChangedListener {
@@ -36272,32 +36512,49 @@
     method public boolean canChangeDtmfToneLength();
     method public java.util.List<android.telephony.CellInfo> getAllCellInfo();
     method public int getCallState();
+    method public int getCallState(int);
     method public android.telephony.CellLocation getCellLocation();
     method public int getDataActivity();
+    method public int getDataNetworkType(int);
     method public int getDataState();
     method public java.lang.String getDeviceId();
     method public java.lang.String getDeviceId(int);
     method public java.lang.String getDeviceSoftwareVersion();
     method public java.lang.String getGroupIdLevel1();
+    method public java.lang.String getGroupIdLevel1(int);
     method public java.lang.String getIccSimChallengeResponse(int, java.lang.String);
+    method public java.lang.String getLine1AlphaTag(int);
     method public java.lang.String getLine1Number();
+    method public java.lang.String getLine1Number(int);
     method public java.lang.String getMmsUAProfUrl();
     method public java.lang.String getMmsUserAgent();
     method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
     method public java.lang.String getNetworkCountryIso();
+    method public java.lang.String getNetworkCountryIso(int);
     method public java.lang.String getNetworkOperator();
+    method public java.lang.String getNetworkOperator(int);
     method public java.lang.String getNetworkOperatorName();
+    method public java.lang.String getNetworkOperatorName(int);
     method public int getNetworkType();
+    method public int getNetworkType(int);
     method public int getPhoneCount();
     method public int getPhoneType();
     method public java.lang.String getSimCountryIso();
+    method public java.lang.String getSimCountryIso(int);
     method public java.lang.String getSimOperator();
+    method public java.lang.String getSimOperator(int);
     method public java.lang.String getSimOperatorName();
+    method public java.lang.String getSimOperatorName(int);
     method public java.lang.String getSimSerialNumber();
+    method public java.lang.String getSimSerialNumber(int);
     method public int getSimState();
     method public java.lang.String getSubscriberId();
+    method public java.lang.String getSubscriberId(int);
     method public java.lang.String getVoiceMailAlphaTag();
+    method public java.lang.String getVoiceMailAlphaTag(int);
     method public java.lang.String getVoiceMailNumber();
+    method public java.lang.String getVoiceMailNumber(int);
+    method public int getVoiceNetworkType(int);
     method public android.net.Uri getVoicemailRingtoneUri(android.telecom.PhoneAccountHandle);
     method public boolean hasCarrierPrivileges();
     method public boolean hasIccCard();
@@ -36308,6 +36565,7 @@
     method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
     method public boolean isHearingAidCompatibilitySupported();
     method public boolean isNetworkRoaming();
+    method public boolean isNetworkRoaming(int);
     method public boolean isSmsCapable();
     method public boolean isTtyModeSupported();
     method public boolean isVoiceCapable();
@@ -36316,9 +36574,11 @@
     method public void listen(android.telephony.PhoneStateListener, int);
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
     method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
+    method public boolean setLine1NumberForDisplay(int, java.lang.String, java.lang.String);
     method public boolean setOperatorBrandOverride(java.lang.String);
     method public boolean setPreferredNetworkTypeToGlobal();
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
+    method public boolean setVoiceMailNumber(int, java.lang.String, java.lang.String);
     field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
     field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
     field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -37247,9 +37507,23 @@
 
   public class Html {
     method public static java.lang.String escapeHtml(java.lang.CharSequence);
-    method public static android.text.Spanned fromHtml(java.lang.String);
-    method public static android.text.Spanned fromHtml(java.lang.String, android.text.Html.ImageGetter, android.text.Html.TagHandler);
-    method public static java.lang.String toHtml(android.text.Spanned);
+    method public static deprecated android.text.Spanned fromHtml(java.lang.String);
+    method public static android.text.Spanned fromHtml(java.lang.String, int);
+    method public static deprecated android.text.Spanned fromHtml(java.lang.String, android.text.Html.ImageGetter, android.text.Html.TagHandler);
+    method public static android.text.Spanned fromHtml(java.lang.String, int, android.text.Html.ImageGetter, android.text.Html.TagHandler);
+    method public static deprecated java.lang.String toHtml(android.text.Spanned);
+    method public static java.lang.String toHtml(android.text.Spanned, int);
+    field public static final int FROM_HTML_MODE_COMPACT = 63; // 0x3f
+    field public static final int FROM_HTML_MODE_LEGACY = 0; // 0x0
+    field public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256; // 0x100
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32; // 0x20
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16; // 0x10
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2; // 0x2
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8; // 0x8
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4; // 0x4
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1; // 0x1
+    field public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0; // 0x0
+    field public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1; // 0x1
   }
 
   public static abstract interface Html.ImageGetter {
@@ -48100,7 +48374,6 @@
     method public boolean setReadable(boolean);
     method public boolean setWritable(boolean, boolean);
     method public boolean setWritable(boolean);
-    method public java.nio.file.Path toPath();
     method public java.net.URI toURI();
     method public deprecated java.net.URL toURL() throws java.net.MalformedURLException;
     field public static final java.lang.String pathSeparator;
@@ -49653,6 +49926,9 @@
     field public static final java.lang.Class<java.lang.Float> TYPE;
   }
 
+  public abstract class FunctionalInterface implements java.lang.annotation.Annotation {
+  }
+
   public class IllegalAccessError extends java.lang.IncompatibleClassChangeError {
     ctor public IllegalAccessError();
     ctor public IllegalAccessError(java.lang.String);
@@ -50782,6 +51058,7 @@
     method public java.lang.Object invoke(java.lang.Object, java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
     method public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>);
     method public boolean isBridge();
+    method public boolean isDefault();
     method public boolean isSynthetic();
     method public boolean isVarArgs();
     method public java.lang.String toGenericString();
@@ -52195,25 +52472,6 @@
     ctor public AsynchronousCloseException();
   }
 
-  public abstract class AsynchronousFileChannel implements java.nio.channels.AsynchronousChannel {
-    ctor protected AsynchronousFileChannel();
-    method public abstract void force(boolean) throws java.io.IOException;
-    method public abstract void lock(long, long, boolean, A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock, ? super A>);
-    method public final void lock(A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock, ? super A>);
-    method public abstract java.util.concurrent.Future<java.nio.channels.FileLock> lock(long, long, boolean);
-    method public final java.util.concurrent.Future<java.nio.channels.FileLock> lock();
-    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public abstract void read(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer, long);
-    method public abstract long size() throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousFileChannel truncate(long) throws java.io.IOException;
-    method public abstract java.nio.channels.FileLock tryLock(long, long, boolean) throws java.io.IOException;
-    method public final java.nio.channels.FileLock tryLock() throws java.io.IOException;
-    method public abstract void write(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer, long);
-  }
-
   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>);
@@ -52322,8 +52580,6 @@
     method public abstract java.nio.channels.FileLock lock(long, long, boolean) throws java.io.IOException;
     method public final java.nio.channels.FileLock lock() throws java.io.IOException;
     method public abstract java.nio.MappedByteBuffer map(java.nio.channels.FileChannel.MapMode, long, long) throws java.io.IOException;
-    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
     method public abstract long position() throws java.io.IOException;
     method public abstract java.nio.channels.FileChannel position(long) throws java.io.IOException;
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
@@ -52350,7 +52606,6 @@
 
   public abstract class FileLock implements java.lang.AutoCloseable {
     ctor protected FileLock(java.nio.channels.FileChannel, long, long, boolean);
-    ctor protected FileLock(java.nio.channels.AsynchronousFileChannel, long, long, boolean);
     method public java.nio.channels.Channel acquiredBy();
     method public final java.nio.channels.FileChannel channel();
     method public final void close() throws java.io.IOException;
@@ -52800,592 +53055,6 @@
 
 }
 
-package java.nio.file {
-
-  public class AccessDeniedException extends java.nio.file.FileSystemException {
-    ctor public AccessDeniedException(java.lang.String);
-    ctor public AccessDeniedException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public final class AccessMode extends java.lang.Enum {
-    method public static java.nio.file.AccessMode valueOf(java.lang.String);
-    method public static final java.nio.file.AccessMode[] values();
-    enum_constant public static final java.nio.file.AccessMode EXECUTE;
-    enum_constant public static final java.nio.file.AccessMode READ;
-    enum_constant public static final java.nio.file.AccessMode WRITE;
-  }
-
-  public class AtomicMoveNotSupportedException extends java.nio.file.FileSystemException {
-    ctor public AtomicMoveNotSupportedException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public class ClosedDirectoryStreamException extends java.lang.IllegalStateException {
-    ctor public ClosedDirectoryStreamException();
-  }
-
-  public class ClosedFileSystemException extends java.lang.IllegalStateException {
-    ctor public ClosedFileSystemException();
-  }
-
-  public class ClosedWatchServiceException extends java.lang.IllegalStateException {
-    ctor public ClosedWatchServiceException();
-  }
-
-  public abstract interface CopyOption {
-  }
-
-  public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
-    ctor public DirectoryIteratorException(java.io.IOException);
-  }
-
-  public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
-    ctor public DirectoryNotEmptyException(java.lang.String);
-  }
-
-  public abstract interface DirectoryStream implements java.io.Closeable java.lang.Iterable {
-    method public abstract java.util.Iterator<T> iterator();
-  }
-
-  public static abstract interface DirectoryStream.Filter {
-    method public abstract boolean accept(T) throws java.io.IOException;
-  }
-
-  public class FileAlreadyExistsException extends java.nio.file.FileSystemException {
-    ctor public FileAlreadyExistsException(java.lang.String);
-    ctor public FileAlreadyExistsException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public abstract class FileStore {
-    ctor protected FileStore();
-    method public abstract java.lang.Object getAttribute(java.lang.String) throws java.io.IOException;
-    method public abstract V getFileStoreAttributeView(java.lang.Class<V>);
-    method public abstract long getTotalSpace() throws java.io.IOException;
-    method public abstract long getUnallocatedSpace() throws java.io.IOException;
-    method public abstract long getUsableSpace() throws java.io.IOException;
-    method public abstract boolean isReadOnly();
-    method public abstract java.lang.String name();
-    method public abstract boolean supportsFileAttributeView(java.lang.Class<? extends java.nio.file.attribute.FileAttributeView>);
-    method public abstract boolean supportsFileAttributeView(java.lang.String);
-    method public abstract java.lang.String type();
-  }
-
-  public abstract class FileSystem implements java.io.Closeable {
-    ctor protected FileSystem();
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.lang.Iterable<java.nio.file.FileStore> getFileStores();
-    method public abstract java.nio.file.Path getPath(java.lang.String, java.lang.String...);
-    method public abstract java.nio.file.PathMatcher getPathMatcher(java.lang.String);
-    method public abstract java.lang.Iterable<java.nio.file.Path> getRootDirectories();
-    method public abstract java.lang.String getSeparator();
-    method public abstract java.nio.file.attribute.UserPrincipalLookupService getUserPrincipalLookupService();
-    method public abstract boolean isOpen();
-    method public abstract boolean isReadOnly();
-    method public abstract java.nio.file.WatchService newWatchService() throws java.io.IOException;
-    method public abstract java.nio.file.spi.FileSystemProvider provider();
-    method public abstract java.util.Set<java.lang.String> supportedFileAttributeViews();
-  }
-
-  public class FileSystemAlreadyExistsException extends java.lang.RuntimeException {
-    ctor public FileSystemAlreadyExistsException();
-    ctor public FileSystemAlreadyExistsException(java.lang.String);
-  }
-
-  public class FileSystemException extends java.io.IOException {
-    ctor public FileSystemException(java.lang.String);
-    ctor public FileSystemException(java.lang.String, java.lang.String, java.lang.String);
-    method public java.lang.String getFile();
-    method public java.lang.String getOtherFile();
-    method public java.lang.String getReason();
-  }
-
-  public class FileSystemLoopException extends java.nio.file.FileSystemException {
-    ctor public FileSystemLoopException(java.lang.String);
-  }
-
-  public class FileSystemNotFoundException extends java.lang.RuntimeException {
-    ctor public FileSystemNotFoundException();
-    ctor public FileSystemNotFoundException(java.lang.String);
-  }
-
-  public final class FileSystems {
-    method public static java.nio.file.FileSystem getDefault();
-    method public static java.nio.file.FileSystem getFileSystem(java.net.URI);
-    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>) throws java.io.IOException;
-    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>, java.lang.ClassLoader) throws java.io.IOException;
-    method public static java.nio.file.FileSystem newFileSystem(java.nio.file.Path, java.lang.ClassLoader) throws java.io.IOException;
-  }
-
-  public final class FileVisitOption extends java.lang.Enum {
-    method public static java.nio.file.FileVisitOption valueOf(java.lang.String);
-    method public static final java.nio.file.FileVisitOption[] values();
-    enum_constant public static final java.nio.file.FileVisitOption FOLLOW_LINKS;
-  }
-
-  public final class FileVisitResult extends java.lang.Enum {
-    method public static java.nio.file.FileVisitResult valueOf(java.lang.String);
-    method public static final java.nio.file.FileVisitResult[] values();
-    enum_constant public static final java.nio.file.FileVisitResult CONTINUE;
-    enum_constant public static final java.nio.file.FileVisitResult SKIP_SIBLINGS;
-    enum_constant public static final java.nio.file.FileVisitResult SKIP_SUBTREE;
-    enum_constant public static final java.nio.file.FileVisitResult TERMINATE;
-  }
-
-  public abstract interface FileVisitor {
-    method public abstract java.nio.file.FileVisitResult postVisitDirectory(T, java.io.IOException) throws java.io.IOException;
-    method public abstract java.nio.file.FileVisitResult preVisitDirectory(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public abstract java.nio.file.FileVisitResult visitFile(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public abstract java.nio.file.FileVisitResult visitFileFailed(T, java.io.IOException) throws java.io.IOException;
-  }
-
-  public final class Files {
-    method public static java.nio.file.Path copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static long copy(java.io.InputStream, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static long copy(java.nio.file.Path, java.io.OutputStream) throws java.io.IOException;
-    method public static java.nio.file.Path createDirectories(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createFile(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempDirectory(java.nio.file.Path, java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempDirectory(java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempFile(java.nio.file.Path, java.lang.String, java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempFile(java.lang.String, java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static void delete(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean exists(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static java.lang.Object getAttribute(java.nio.file.Path, java.lang.String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static V getFileAttributeView(java.nio.file.Path, java.lang.Class<V>, java.nio.file.LinkOption...);
-    method public static java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.attribute.FileTime getLastModifiedTime(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.attribute.UserPrincipal getOwner(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> getPosixFilePermissions(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static boolean isDirectory(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static boolean isExecutable(java.nio.file.Path);
-    method public static boolean isHidden(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean isReadable(java.nio.file.Path);
-    method public static boolean isRegularFile(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public static boolean isSymbolicLink(java.nio.file.Path);
-    method public static boolean isWritable(java.nio.file.Path);
-    method public static java.nio.file.Path move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static java.io.BufferedReader newBufferedReader(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
-    method public static java.io.BufferedWriter newBufferedWriter(java.nio.file.Path, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.lang.String) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static boolean notExists(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static java.lang.String probeContentType(java.nio.file.Path) throws java.io.IOException;
-    method public static byte[] readAllBytes(java.nio.file.Path) throws java.io.IOException;
-    method public static java.util.List<java.lang.String> readAllLines(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
-    method public static A readAttributes(java.nio.file.Path, java.lang.Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.util.Map<java.lang.String, java.lang.Object> readAttributes(java.nio.file.Path, java.lang.String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path setAttribute(java.nio.file.Path, java.lang.String, java.lang.Object, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.Path setLastModifiedTime(java.nio.file.Path, java.nio.file.attribute.FileTime) throws java.io.IOException;
-    method public static java.nio.file.Path setOwner(java.nio.file.Path, java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
-    method public static java.nio.file.Path setPosixFilePermissions(java.nio.file.Path, java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
-    method public static long size(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.util.Set<java.nio.file.FileVisitOption>, int, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.nio.file.Path write(java.nio.file.Path, byte[], java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.file.Path write(java.nio.file.Path, java.lang.Iterable<? extends java.lang.CharSequence>, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
-  }
-
-  public class InvalidPathException extends java.lang.IllegalArgumentException {
-    ctor public InvalidPathException(java.lang.String, java.lang.String, int);
-    ctor public InvalidPathException(java.lang.String, java.lang.String);
-    method public int getIndex();
-    method public java.lang.String getInput();
-    method public java.lang.String getReason();
-  }
-
-  public final class LinkOption extends java.lang.Enum implements java.nio.file.CopyOption java.nio.file.OpenOption {
-    method public static java.nio.file.LinkOption valueOf(java.lang.String);
-    method public static final java.nio.file.LinkOption[] values();
-    enum_constant public static final java.nio.file.LinkOption NOFOLLOW_LINKS;
-  }
-
-  public final class LinkPermission extends java.security.BasicPermission {
-    ctor public LinkPermission(java.lang.String);
-    ctor public LinkPermission(java.lang.String, java.lang.String);
-  }
-
-  public class NoSuchFileException extends java.nio.file.FileSystemException {
-    ctor public NoSuchFileException(java.lang.String);
-    ctor public NoSuchFileException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public class NotDirectoryException extends java.nio.file.FileSystemException {
-    ctor public NotDirectoryException(java.lang.String);
-  }
-
-  public class NotLinkException extends java.nio.file.FileSystemException {
-    ctor public NotLinkException(java.lang.String);
-    ctor public NotLinkException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public abstract interface OpenOption {
-  }
-
-  public abstract interface Path implements java.lang.Comparable java.lang.Iterable java.nio.file.Watchable {
-    method public abstract int compareTo(java.nio.file.Path);
-    method public abstract boolean endsWith(java.nio.file.Path);
-    method public abstract boolean endsWith(java.lang.String);
-    method public abstract boolean equals(java.lang.Object);
-    method public abstract java.nio.file.Path getFileName();
-    method public abstract java.nio.file.FileSystem getFileSystem();
-    method public abstract java.nio.file.Path getName(int);
-    method public abstract int getNameCount();
-    method public abstract java.nio.file.Path getParent();
-    method public abstract java.nio.file.Path getRoot();
-    method public abstract int hashCode();
-    method public abstract boolean isAbsolute();
-    method public abstract java.util.Iterator<java.nio.file.Path> iterator();
-    method public abstract java.nio.file.Path normalize();
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>[], java.nio.file.WatchEvent.Modifier...) throws java.io.IOException;
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.Path relativize(java.nio.file.Path);
-    method public abstract java.nio.file.Path resolve(java.nio.file.Path);
-    method public abstract java.nio.file.Path resolve(java.lang.String);
-    method public abstract java.nio.file.Path resolveSibling(java.nio.file.Path);
-    method public abstract java.nio.file.Path resolveSibling(java.lang.String);
-    method public abstract boolean startsWith(java.nio.file.Path);
-    method public abstract boolean startsWith(java.lang.String);
-    method public abstract java.nio.file.Path subpath(int, int);
-    method public abstract java.nio.file.Path toAbsolutePath();
-    method public abstract java.io.File toFile();
-    method public abstract java.nio.file.Path toRealPath(java.nio.file.LinkOption...) throws java.io.IOException;
-    method public abstract java.lang.String toString();
-    method public abstract java.net.URI toUri();
-  }
-
-  public abstract interface PathMatcher {
-    method public abstract boolean matches(java.nio.file.Path);
-  }
-
-  public final class Paths {
-    method public static java.nio.file.Path get(java.lang.String, java.lang.String...);
-    method public static java.nio.file.Path get(java.net.URI);
-  }
-
-  public class ProviderMismatchException extends java.lang.IllegalArgumentException {
-    ctor public ProviderMismatchException();
-    ctor public ProviderMismatchException(java.lang.String);
-  }
-
-  public class ProviderNotFoundException extends java.lang.RuntimeException {
-    ctor public ProviderNotFoundException();
-    ctor public ProviderNotFoundException(java.lang.String);
-  }
-
-  public class ReadOnlyFileSystemException extends java.lang.UnsupportedOperationException {
-    ctor public ReadOnlyFileSystemException();
-  }
-
-  public abstract interface SecureDirectoryStream implements java.nio.file.DirectoryStream {
-    method public abstract void deleteDirectory(T) throws java.io.IOException;
-    method public abstract void deleteFile(T) throws java.io.IOException;
-    method public abstract V getFileAttributeView(java.lang.Class<V>);
-    method public abstract V getFileAttributeView(T, java.lang.Class<V>, java.nio.file.LinkOption...);
-    method public abstract void move(T, java.nio.file.SecureDirectoryStream<T>, T) throws java.io.IOException;
-    method public abstract java.nio.channels.SeekableByteChannel newByteChannel(T, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.SecureDirectoryStream<T> newDirectoryStream(T, java.nio.file.LinkOption...) throws java.io.IOException;
-  }
-
-  public final class StandardCopyOption extends java.lang.Enum implements java.nio.file.CopyOption {
-    method public static java.nio.file.StandardCopyOption valueOf(java.lang.String);
-    method public static final java.nio.file.StandardCopyOption[] values();
-    enum_constant public static final java.nio.file.StandardCopyOption ATOMIC_MOVE;
-    enum_constant public static final java.nio.file.StandardCopyOption COPY_ATTRIBUTES;
-    enum_constant public static final java.nio.file.StandardCopyOption REPLACE_EXISTING;
-  }
-
-  public final class StandardOpenOption extends java.lang.Enum implements java.nio.file.OpenOption {
-    method public static java.nio.file.StandardOpenOption valueOf(java.lang.String);
-    method public static final java.nio.file.StandardOpenOption[] values();
-    enum_constant public static final java.nio.file.StandardOpenOption APPEND;
-    enum_constant public static final java.nio.file.StandardOpenOption CREATE;
-    enum_constant public static final java.nio.file.StandardOpenOption CREATE_NEW;
-    enum_constant public static final java.nio.file.StandardOpenOption DELETE_ON_CLOSE;
-    enum_constant public static final java.nio.file.StandardOpenOption DSYNC;
-    enum_constant public static final java.nio.file.StandardOpenOption READ;
-    enum_constant public static final java.nio.file.StandardOpenOption SPARSE;
-    enum_constant public static final java.nio.file.StandardOpenOption SYNC;
-    enum_constant public static final java.nio.file.StandardOpenOption TRUNCATE_EXISTING;
-    enum_constant public static final java.nio.file.StandardOpenOption WRITE;
-  }
-
-  public final class StandardWatchEventKinds {
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_CREATE;
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_DELETE;
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_MODIFY;
-    field public static final java.nio.file.WatchEvent.Kind<java.lang.Object> OVERFLOW;
-  }
-
-  public abstract interface WatchEvent {
-    method public abstract T context();
-    method public abstract int count();
-    method public abstract java.nio.file.WatchEvent.Kind<T> kind();
-  }
-
-  public static abstract interface WatchEvent.Kind {
-    method public abstract java.lang.String name();
-    method public abstract java.lang.Class<T> type();
-  }
-
-  public static abstract interface WatchEvent.Modifier {
-    method public abstract java.lang.String name();
-  }
-
-  public abstract interface WatchKey {
-    method public abstract void cancel();
-    method public abstract boolean isValid();
-    method public abstract java.util.List<java.nio.file.WatchEvent<?>> pollEvents();
-    method public abstract boolean reset();
-    method public abstract java.nio.file.Watchable watchable();
-  }
-
-  public abstract interface WatchService implements java.io.Closeable {
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.nio.file.WatchKey poll();
-    method public abstract java.nio.file.WatchKey poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public abstract java.nio.file.WatchKey take() throws java.lang.InterruptedException;
-  }
-
-  public abstract interface Watchable {
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>[], java.nio.file.WatchEvent.Modifier...) throws java.io.IOException;
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>...) throws java.io.IOException;
-  }
-
-}
-
-package java.nio.file.attribute {
-
-  public final class AclEntry {
-    method public java.util.Set<java.nio.file.attribute.AclEntryFlag> flags();
-    method public static java.nio.file.attribute.AclEntry.Builder newBuilder();
-    method public static java.nio.file.attribute.AclEntry.Builder newBuilder(java.nio.file.attribute.AclEntry);
-    method public java.util.Set<java.nio.file.attribute.AclEntryPermission> permissions();
-    method public java.nio.file.attribute.UserPrincipal principal();
-    method public java.nio.file.attribute.AclEntryType type();
-  }
-
-  public static final class AclEntry.Builder {
-    method public java.nio.file.attribute.AclEntry build();
-    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.util.Set<java.nio.file.attribute.AclEntryFlag>);
-    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.nio.file.attribute.AclEntryFlag...);
-    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.util.Set<java.nio.file.attribute.AclEntryPermission>);
-    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.nio.file.attribute.AclEntryPermission...);
-    method public java.nio.file.attribute.AclEntry.Builder setPrincipal(java.nio.file.attribute.UserPrincipal);
-    method public java.nio.file.attribute.AclEntry.Builder setType(java.nio.file.attribute.AclEntryType);
-  }
-
-  public final class AclEntryFlag extends java.lang.Enum {
-    method public static java.nio.file.attribute.AclEntryFlag valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.AclEntryFlag[] values();
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag DIRECTORY_INHERIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag FILE_INHERIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag INHERIT_ONLY;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag NO_PROPAGATE_INHERIT;
-  }
-
-  public final class AclEntryPermission extends java.lang.Enum {
-    method public static java.nio.file.attribute.AclEntryPermission valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.AclEntryPermission[] values();
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission APPEND_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE_CHILD;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission EXECUTE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ACL;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ATTRIBUTES;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_NAMED_ATTRS;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission SYNCHRONIZE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ACL;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ATTRIBUTES;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_NAMED_ATTRS;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_OWNER;
-    field public static final java.nio.file.attribute.AclEntryPermission ADD_FILE;
-    field public static final java.nio.file.attribute.AclEntryPermission ADD_SUBDIRECTORY;
-    field public static final java.nio.file.attribute.AclEntryPermission LIST_DIRECTORY;
-  }
-
-  public final class AclEntryType extends java.lang.Enum {
-    method public static java.nio.file.attribute.AclEntryType valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.AclEntryType[] values();
-    enum_constant public static final java.nio.file.attribute.AclEntryType ALARM;
-    enum_constant public static final java.nio.file.attribute.AclEntryType ALLOW;
-    enum_constant public static final java.nio.file.attribute.AclEntryType AUDIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryType DENY;
-  }
-
-  public abstract interface AclFileAttributeView implements java.nio.file.attribute.FileOwnerAttributeView {
-    method public abstract java.util.List<java.nio.file.attribute.AclEntry> getAcl() throws java.io.IOException;
-    method public abstract java.lang.String name();
-    method public abstract void setAcl(java.util.List<java.nio.file.attribute.AclEntry>) throws java.io.IOException;
-  }
-
-  public abstract interface AttributeView {
-    method public abstract java.lang.String name();
-  }
-
-  public abstract interface BasicFileAttributeView implements java.nio.file.attribute.FileAttributeView {
-    method public abstract java.lang.String name();
-    method public abstract java.nio.file.attribute.BasicFileAttributes readAttributes() throws java.io.IOException;
-    method public abstract void setTimes(java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime) throws java.io.IOException;
-  }
-
-  public abstract interface BasicFileAttributes {
-    method public abstract java.nio.file.attribute.FileTime creationTime();
-    method public abstract java.lang.Object fileKey();
-    method public abstract boolean isDirectory();
-    method public abstract boolean isOther();
-    method public abstract boolean isRegularFile();
-    method public abstract boolean isSymbolicLink();
-    method public abstract java.nio.file.attribute.FileTime lastAccessTime();
-    method public abstract java.nio.file.attribute.FileTime lastModifiedTime();
-    method public abstract long size();
-  }
-
-  public abstract interface DosFileAttributeView implements java.nio.file.attribute.BasicFileAttributeView {
-    method public abstract java.lang.String name();
-    method public abstract java.nio.file.attribute.DosFileAttributes readAttributes() throws java.io.IOException;
-    method public abstract void setArchive(boolean) throws java.io.IOException;
-    method public abstract void setHidden(boolean) throws java.io.IOException;
-    method public abstract void setReadOnly(boolean) throws java.io.IOException;
-    method public abstract void setSystem(boolean) throws java.io.IOException;
-  }
-
-  public abstract interface DosFileAttributes implements java.nio.file.attribute.BasicFileAttributes {
-    method public abstract boolean isArchive();
-    method public abstract boolean isHidden();
-    method public abstract boolean isReadOnly();
-    method public abstract boolean isSystem();
-  }
-
-  public abstract interface FileAttribute {
-    method public abstract java.lang.String name();
-    method public abstract T value();
-  }
-
-  public abstract interface FileAttributeView implements java.nio.file.attribute.AttributeView {
-  }
-
-  public abstract interface FileOwnerAttributeView implements java.nio.file.attribute.FileAttributeView {
-    method public abstract java.nio.file.attribute.UserPrincipal getOwner() throws java.io.IOException;
-    method public abstract java.lang.String name();
-    method public abstract void setOwner(java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
-  }
-
-  public abstract interface FileStoreAttributeView implements java.nio.file.attribute.AttributeView {
-  }
-
-  public final class FileTime implements java.lang.Comparable {
-    method public int compareTo(java.nio.file.attribute.FileTime);
-    method public static java.nio.file.attribute.FileTime from(long, java.util.concurrent.TimeUnit);
-    method public static java.nio.file.attribute.FileTime fromMillis(long);
-    method public long to(java.util.concurrent.TimeUnit);
-    method public long toMillis();
-  }
-
-  public abstract interface GroupPrincipal implements java.nio.file.attribute.UserPrincipal {
-  }
-
-  public abstract interface PosixFileAttributeView implements java.nio.file.attribute.BasicFileAttributeView java.nio.file.attribute.FileOwnerAttributeView {
-    method public abstract java.lang.String name();
-    method public abstract java.nio.file.attribute.PosixFileAttributes readAttributes() throws java.io.IOException;
-    method public abstract void setGroup(java.nio.file.attribute.GroupPrincipal) throws java.io.IOException;
-    method public abstract void setPermissions(java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
-  }
-
-  public abstract interface PosixFileAttributes implements java.nio.file.attribute.BasicFileAttributes {
-    method public abstract java.nio.file.attribute.GroupPrincipal group();
-    method public abstract java.nio.file.attribute.UserPrincipal owner();
-    method public abstract java.util.Set<java.nio.file.attribute.PosixFilePermission> permissions();
-  }
-
-  public final class PosixFilePermission extends java.lang.Enum {
-    method public static java.nio.file.attribute.PosixFilePermission valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.PosixFilePermission[] values();
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_WRITE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_WRITE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_WRITE;
-  }
-
-  public final class PosixFilePermissions {
-    method public static java.nio.file.attribute.FileAttribute<java.util.Set<java.nio.file.attribute.PosixFilePermission>> asFileAttribute(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
-    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> fromString(java.lang.String);
-    method public static java.lang.String toString(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
-  }
-
-  public abstract interface UserPrincipal implements java.security.Principal {
-  }
-
-  public abstract class UserPrincipalLookupService {
-    ctor protected UserPrincipalLookupService();
-    method public abstract java.nio.file.attribute.GroupPrincipal lookupPrincipalByGroupName(java.lang.String) throws java.io.IOException;
-    method public abstract java.nio.file.attribute.UserPrincipal lookupPrincipalByName(java.lang.String) throws java.io.IOException;
-  }
-
-  public class UserPrincipalNotFoundException extends java.io.IOException {
-    ctor public UserPrincipalNotFoundException(java.lang.String);
-    method public java.lang.String getName();
-  }
-
-}
-
-package java.nio.file.spi {
-
-  public abstract class FileSystemProvider {
-    ctor protected FileSystemProvider();
-    method public abstract void checkAccess(java.nio.file.Path, java.nio.file.AccessMode...) throws java.io.IOException;
-    method public abstract void copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public abstract void createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public void createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public void createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract void delete(java.nio.file.Path) throws java.io.IOException;
-    method public boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
-    method public abstract V getFileAttributeView(java.nio.file.Path, java.lang.Class<V>, java.nio.file.LinkOption...);
-    method public abstract java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
-    method public abstract java.nio.file.FileSystem getFileSystem(java.net.URI);
-    method public abstract java.nio.file.Path getPath(java.net.URI);
-    method public abstract java.lang.String getScheme();
-    method public static java.util.List<java.nio.file.spi.FileSystemProvider> installedProviders();
-    method public abstract boolean isHidden(java.nio.file.Path) throws java.io.IOException;
-    method public abstract boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public abstract void move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public java.nio.channels.AsynchronousFileChannel newAsynchronousFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
-    method public java.nio.channels.FileChannel newFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>) throws java.io.IOException;
-    method public java.nio.file.FileSystem newFileSystem(java.nio.file.Path, java.util.Map<java.lang.String, ?>) throws java.io.IOException;
-    method public java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public abstract A readAttributes(java.nio.file.Path, java.lang.Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public abstract java.util.Map<java.lang.String, java.lang.Object> readAttributes(java.nio.file.Path, java.lang.String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
-    method public abstract void setAttribute(java.nio.file.Path, java.lang.String, java.lang.Object, java.nio.file.LinkOption...) throws java.io.IOException;
-  }
-
-  public abstract class FileTypeDetector {
-    ctor protected FileTypeDetector();
-    method public abstract java.lang.String probeContentType(java.nio.file.Path) throws java.io.IOException;
-  }
-
-}
-
 package java.security {
 
   public final class AccessControlContext {
@@ -57982,8 +57651,6 @@
     ctor public Scanner(java.io.InputStream, java.lang.String);
     ctor public Scanner(java.io.File) throws java.io.FileNotFoundException;
     ctor public Scanner(java.io.File, java.lang.String) throws java.io.FileNotFoundException;
-    ctor public Scanner(java.nio.file.Path) throws java.io.IOException;
-    ctor public Scanner(java.nio.file.Path, java.lang.String) throws java.io.IOException;
     ctor public Scanner(java.lang.String);
     ctor public Scanner(java.nio.channels.ReadableByteChannel);
     ctor public Scanner(java.nio.channels.ReadableByteChannel, java.lang.String);
diff --git a/api/system-current.txt b/api/system-current.txt
index 7118abc..4668065 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -95,7 +95,7 @@
     field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
     field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK";
     field public static final java.lang.String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
-    field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
+    field public static final deprecated java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
     field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
     field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS";
     field public static final java.lang.String GET_PACKAGE_IMPORTANCE = "android.permission.GET_PACKAGE_IMPORTANCE";
@@ -1282,6 +1282,7 @@
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsAssist = 16844016; // 0x10104f0
     field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
+    field public static final int supportsLocalInteraction = 16844048; // 0x1010510
     field public static final int supportsPictureInPicture = 16844024; // 0x10104f8
     field public static final int supportsRtl = 16843695; // 0x10103af
     field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
@@ -2902,6 +2903,7 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> confirmCredentials(android.accounts.Account, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
+    method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSessionAsUser(android.os.Bundle, android.app.Activity, android.os.UserHandle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public static android.accounts.AccountManager get(android.content.Context);
     method public android.accounts.Account[] getAccounts();
     method public android.accounts.Account[] getAccountsByType(java.lang.String);
@@ -3551,6 +3553,7 @@
     method public boolean isDestroyed();
     method public boolean isFinishing();
     method public boolean isImmersive();
+    method public boolean isLocalVoiceInteractionSupported();
     method public boolean isTaskRoot();
     method public boolean isVoiceInteraction();
     method public boolean isVoiceInteractionRoot();
@@ -3593,6 +3596,8 @@
     method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
     method public boolean onKeyShortcut(int, android.view.KeyEvent);
     method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public void onLocalVoiceInteractionStarted();
+    method public void onLocalVoiceInteractionStopped();
     method public void onLowMemory();
     method public boolean onMenuItemSelected(int, android.view.MenuItem);
     method public boolean onMenuOpened(int, android.view.Menu);
@@ -3707,12 +3712,14 @@
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSenderFromChild(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSenderFromChild(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void startLocalVoiceInteraction(android.os.Bundle);
     method public void startLockTask();
     method public deprecated void startManagingCursor(android.database.Cursor);
     method public boolean startNextMatchingActivity(android.content.Intent);
     method public boolean startNextMatchingActivity(android.content.Intent, android.os.Bundle);
     method public void startPostponedEnterTransition();
     method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
+    method public void stopLocalVoiceInteraction();
     method public void stopLockTask();
     method public deprecated void stopManagingCursor(android.database.Cursor);
     method public void takeKeyEvents(boolean);
@@ -3792,9 +3799,6 @@
     method public void startActivity(android.content.Context, android.content.Intent, android.os.Bundle);
   }
 
-  public static abstract class ActivityManager.BugreportMode implements java.lang.annotation.Annotation {
-  }
-
   public static class ActivityManager.MemoryInfo implements android.os.Parcelable {
     ctor public ActivityManager.MemoryInfo();
     method public int describeContents();
@@ -5818,12 +5822,15 @@
     method public android.graphics.drawable.Drawable peekFastDrawable();
     method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
     method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
-    method public void setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean, int) throws java.io.IOException;
     method public void setDisplayOffset(android.os.IBinder, int, int);
     method public void setDisplayPadding(android.graphics.Rect);
     method public void setResource(int) throws java.io.IOException;
+    method public int setResource(int, int) throws java.io.IOException;
     method public void setStream(java.io.InputStream) throws java.io.IOException;
-    method public void setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setStream(java.io.InputStream, android.graphics.Rect, boolean, int) throws java.io.IOException;
     method public boolean setWallpaperComponent(android.content.ComponentName);
     method public void setWallpaperOffsetSteps(float, float);
     method public void setWallpaperOffsets(android.os.IBinder, float, float);
@@ -5835,6 +5842,8 @@
     field public static final java.lang.String COMMAND_SECONDARY_TAP = "android.wallpaper.secondaryTap";
     field public static final java.lang.String COMMAND_TAP = "android.wallpaper.tap";
     field public static final java.lang.String EXTRA_LIVE_WALLPAPER_COMPONENT = "android.service.wallpaper.extra.LIVE_WALLPAPER_COMPONENT";
+    field public static final int FLAG_SET_LOCK = 2; // 0x2
+    field public static final int FLAG_SET_SYSTEM = 1; // 0x1
     field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
   }
 
@@ -5907,9 +5916,6 @@
     field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
   }
 
-  public static abstract class DeviceAdminReceiver.BugreportFailureCode implements java.lang.annotation.Annotation {
-  }
-
   public class DevicePolicyManager {
     method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
     method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5921,6 +5927,7 @@
     method public void clearProfileOwner(android.content.ComponentName);
     method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
     method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+    method public android.os.UserHandle createAndManageUser(android.content.ComponentName, java.lang.String, android.content.ComponentName, android.os.PersistableBundle, int);
     method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
     method public void enableSystemApp(android.content.ComponentName, java.lang.String);
     method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
@@ -6125,6 +6132,7 @@
     field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
     field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
     field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
+    field public static final int SKIP_SETUP_WIZARD = 1; // 0x1
     field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
     field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
   }
@@ -6246,6 +6254,7 @@
     method public void onCreate();
     method public void onDestroy();
     method public void onFullBackup(android.app.backup.FullBackupDataOutput) throws java.io.IOException;
+    method public void onQuotaExceeded(long, long);
     method public abstract void onRestore(android.app.backup.BackupDataInput, int, android.os.ParcelFileDescriptor) throws java.io.IOException;
     method public void onRestoreFile(android.os.ParcelFileDescriptor, long, java.io.File, int, long, long) throws java.io.IOException;
     method public void onRestoreFinished();
@@ -6308,6 +6317,7 @@
     field public static final int ERROR_PACKAGE_NOT_FOUND = -2002; // 0xfffff82e
     field public static final int ERROR_TRANSPORT_ABORTED = -1000; // 0xfffffc18
     field public static final int ERROR_TRANSPORT_PACKAGE_REJECTED = -1002; // 0xfffffc16
+    field public static final int ERROR_TRANSPORT_QUOTA_EXCEEDED = -1005; // 0xfffffc13
     field public static final int SUCCESS = 0; // 0x0
   }
 
@@ -6340,6 +6350,7 @@
     method public int finishBackup();
     method public void finishRestore();
     method public android.app.backup.RestoreSet[] getAvailableRestoreSets();
+    method public long getBackupQuota(java.lang.String, boolean);
     method public android.os.IBinder getBinder();
     method public long getCurrentRestoreSet();
     method public int getNextFullRestoreDataChunk(android.os.ParcelFileDescriptor);
@@ -6365,6 +6376,7 @@
     field public static final int TRANSPORT_NOT_INITIALIZED = -1001; // 0xfffffc17
     field public static final int TRANSPORT_OK = 0; // 0x0
     field public static final int TRANSPORT_PACKAGE_REJECTED = -1002; // 0xfffffc16
+    field public static final int TRANSPORT_QUOTA_EXCEEDED = -1005; // 0xfffffc13
   }
 
   public class FileBackupHelper extends android.app.backup.FileBackupHelperBase implements android.app.backup.BackupHelper {
@@ -6440,6 +6452,7 @@
     method public long getMinLatencyMillis();
     method public int getNetworkType();
     method public android.content.ComponentName getService();
+    method public android.app.job.JobInfo.TriggerContentUri[] getTriggerContentUris();
     method public boolean isPeriodic();
     method public boolean isPersisted();
     method public boolean isRequireCharging();
@@ -6459,6 +6472,7 @@
 
   public static final class JobInfo.Builder {
     ctor public JobInfo.Builder(int, android.content.ComponentName);
+    method public android.app.job.JobInfo.Builder addTriggerContentUri(android.app.job.JobInfo.TriggerContentUri);
     method public android.app.job.JobInfo build();
     method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int);
     method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle);
@@ -6472,10 +6486,22 @@
     method public android.app.job.JobInfo.Builder setRequiresDeviceIdle(boolean);
   }
 
+  public static final class JobInfo.TriggerContentUri implements android.os.Parcelable {
+    ctor public JobInfo.TriggerContentUri(android.net.Uri, int);
+    method public int describeContents();
+    method public int getFlags();
+    method public android.net.Uri getUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.job.JobInfo.TriggerContentUri> CREATOR;
+    field public static final int FLAG_NOTIFY_FOR_DESCENDANTS = 1; // 0x1
+  }
+
   public class JobParameters implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.PersistableBundle getExtras();
     method public int getJobId();
+    method public java.lang.String[] getTriggeredContentAuthorities();
+    method public android.net.Uri[] getTriggeredContentUris();
     method public boolean isOverrideDeadlineExpired();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.job.JobParameters> CREATOR;
@@ -7581,6 +7607,8 @@
     method public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
     method public void startScan(android.bluetooth.le.ScanCallback);
     method public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
+    method public void startScanFromSource(android.os.WorkSource, android.bluetooth.le.ScanCallback);
+    method public void startScanFromSource(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.os.WorkSource, android.bluetooth.le.ScanCallback);
     method public void startTruncatedScan(java.util.List<android.bluetooth.le.TruncatedFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
     method public void stopScan(android.bluetooth.le.ScanCallback);
   }
@@ -8305,6 +8333,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
+    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties";
     field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
@@ -8667,7 +8696,6 @@
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
-    field public static final java.lang.String ACTION_AVAILABILITY_CHANGED = "android.intent.action.AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
     field public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
@@ -8754,6 +8782,7 @@
     field public static final java.lang.String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED";
     field public static final java.lang.String ACTION_QUERY_PACKAGE_RESTART = "android.intent.action.QUERY_PACKAGE_RESTART";
     field public static final java.lang.String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK";
+    field public static final java.lang.String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
     field public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT";
     field public static final java.lang.String ACTION_RESOLVE_EPHEMERAL_PACKAGE = "android.intent.action.RESOLVE_EPHEMERAL_PACKAGE";
     field public static final java.lang.String ACTION_RUN = "android.intent.action.RUN";
@@ -8851,6 +8880,7 @@
     field public static final java.lang.String EXTRA_EPHEMERAL_FAILURE = "android.intent.extra.EPHEMERAL_FAILURE";
     field public static final java.lang.String EXTRA_EPHEMERAL_SUCCESS = "android.intent.extra.EPHEMERAL_SUCCESS";
     field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+    field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
     field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
     field public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT";
@@ -9992,6 +10022,7 @@
     field public static final java.lang.String FEATURE_MIDI = "android.software.midi";
     field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
     field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
+    field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef";
     field public static final java.lang.String FEATURE_OPENGLES_EXTENSION_PACK = "android.hardware.opengles.aep";
     field public static final java.lang.String FEATURE_PICTURE_IN_PICTURE = "android.software.picture_in_picture";
     field public static final java.lang.String FEATURE_PRINTING = "android.software.print";
@@ -10480,7 +10511,6 @@
     method public java.lang.String getQuantityString(int, int, java.lang.Object...) throws android.content.res.Resources.NotFoundException;
     method public java.lang.String getQuantityString(int, int) throws android.content.res.Resources.NotFoundException;
     method public java.lang.CharSequence getQuantityText(int, int) throws android.content.res.Resources.NotFoundException;
-    method public java.util.Locale getResolvedLocale();
     method public java.lang.String getResourceEntryName(int) throws android.content.res.Resources.NotFoundException;
     method public java.lang.String getResourceName(int) throws android.content.res.Resources.NotFoundException;
     method public java.lang.String getResourcePackageName(int) throws android.content.res.Resources.NotFoundException;
@@ -13748,6 +13778,7 @@
     field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD = "android.sensor.magnetic_field";
     field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED = "android.sensor.magnetic_field_uncalibrated";
     field public static final deprecated java.lang.String STRING_TYPE_ORIENTATION = "android.sensor.orientation";
+    field public static final java.lang.String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof";
     field public static final java.lang.String STRING_TYPE_PRESSURE = "android.sensor.pressure";
     field public static final java.lang.String STRING_TYPE_PROXIMITY = "android.sensor.proximity";
     field public static final java.lang.String STRING_TYPE_RELATIVE_HUMIDITY = "android.sensor.relative_humidity";
@@ -13771,6 +13802,7 @@
     field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2
     field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe
     field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3
+    field public static final int TYPE_POSE_6DOF = 28; // 0x1c
     field public static final int TYPE_PRESSURE = 6; // 0x6
     field public static final int TYPE_PROXIMITY = 8; // 0x8
     field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
@@ -13975,6 +14007,7 @@
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AF;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AWB;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>> CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> DEPTH_DEPTH_IS_EXCLUSIVE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> EDGE_AVAILABLE_EDGE_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> FLASH_INFO_AVAILABLE;
@@ -14054,9 +14087,11 @@
     method public abstract void close();
     method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
     method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void createCaptureSessionByOutputConfiguration(java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
     method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void createReprocessableCaptureSessionWithConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract java.lang.String getId();
     field public static final int TEMPLATE_MANUAL = 6; // 0x6
     field public static final int TEMPLATE_PREVIEW = 1; // 0x1
@@ -14213,6 +14248,7 @@
     field public static final int HOT_PIXEL_MODE_FAST = 1; // 0x1
     field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2
     field public static final int HOT_PIXEL_MODE_OFF = 0; // 0x0
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3; // 0x3
     field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1
     field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; // 0x2
     field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0
@@ -14334,6 +14370,7 @@
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_SCENE_MODE;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
     field public static final android.os.Parcelable.Creator<android.hardware.camera2.CaptureRequest> CREATOR;
@@ -14412,6 +14449,7 @@
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_SCENE_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> EDGE_MODE;
@@ -14553,6 +14591,24 @@
     field public static final int METERING_WEIGHT_MIN = 0; // 0x0
   }
 
+  public final class OutputConfiguration implements android.os.Parcelable {
+    ctor public OutputConfiguration(android.view.Surface);
+    ctor public OutputConfiguration(android.view.Surface, int);
+    ctor public OutputConfiguration(android.hardware.camera2.params.OutputConfiguration);
+    method public int describeContents();
+    method public int getRotation();
+    method public android.view.Surface getSurface();
+    method public int getSurfaceSetId();
+    method public void setSurfaceSetId(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
+    field public static final int ROTATION_0 = 0; // 0x0
+    field public static final int ROTATION_180 = 2; // 0x2
+    field public static final int ROTATION_270 = 3; // 0x3
+    field public static final int ROTATION_90 = 1; // 0x1
+    field public static final int SURFACE_SET_ID_INVALID = -1; // 0xffffffff
+  }
+
   public final class RggbChannelVector {
     ctor public RggbChannelVector(float, float, float, float);
     method public void copyTo(float[], int);
@@ -21379,6 +21435,7 @@
     field public static final deprecated int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00
     field public static final deprecated int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
     field public static final java.lang.String FEATURE_AdaptivePlayback = "adaptive-playback";
+    field public static final java.lang.String FEATURE_IntraRefresh = "intra-refresh";
     field public static final java.lang.String FEATURE_SecurePlayback = "secure-playback";
     field public static final java.lang.String FEATURE_TunneledPlayback = "tunneled-playback";
     field public int[] colorFormats;
@@ -21421,6 +21478,21 @@
     field public static final int AVCProfileHigh422 = 32; // 0x20
     field public static final int AVCProfileHigh444 = 64; // 0x40
     field public static final int AVCProfileMain = 2; // 0x2
+    field public static final int DolbyVisionLevelFhd24 = 4; // 0x4
+    field public static final int DolbyVisionLevelFhd30 = 8; // 0x8
+    field public static final int DolbyVisionLevelFhd60 = 16; // 0x10
+    field public static final int DolbyVisionLevelHd24 = 1; // 0x1
+    field public static final int DolbyVisionLevelHd30 = 2; // 0x2
+    field public static final int DolbyVisionLevelUhd24 = 32; // 0x20
+    field public static final int DolbyVisionLevelUhd30 = 64; // 0x40
+    field public static final int DolbyVisionLevelUhd48 = 128; // 0x80
+    field public static final int DolbyVisionLevelUhd60 = 256; // 0x100
+    field public static final int DolbyVisionProfileDvavDen = 2; // 0x2
+    field public static final int DolbyVisionProfileDvavDer = 1; // 0x1
+    field public static final int DolbyVisionProfileDvheDen = 4; // 0x4
+    field public static final int DolbyVisionProfileDvheDer = 3; // 0x3
+    field public static final int DolbyVisionProfileDvheDtr = 5; // 0x5
+    field public static final int DolbyVisionProfileDvheStn = 6; // 0x6
     field public static final int H263Level10 = 1; // 0x1
     field public static final int H263Level20 = 2; // 0x2
     field public static final int H263Level30 = 4; // 0x4
@@ -21505,6 +21577,24 @@
     field public static final int VP8Level_Version2 = 4; // 0x4
     field public static final int VP8Level_Version3 = 8; // 0x8
     field public static final int VP8ProfileMain = 1; // 0x1
+    field public static final int VP9Level1 = 0; // 0x0
+    field public static final int VP9Level11 = 1; // 0x1
+    field public static final int VP9Level2 = 2; // 0x2
+    field public static final int VP9Level21 = 4; // 0x4
+    field public static final int VP9Level3 = 8; // 0x8
+    field public static final int VP9Level31 = 16; // 0x10
+    field public static final int VP9Level4 = 32; // 0x20
+    field public static final int VP9Level41 = 64; // 0x40
+    field public static final int VP9Level5 = 128; // 0x80
+    field public static final int VP9Level51 = 256; // 0x100
+    field public static final int VP9Level52 = 512; // 0x200
+    field public static final int VP9Level6 = 1024; // 0x400
+    field public static final int VP9Level61 = 2048; // 0x800
+    field public static final int VP9Level62 = 4096; // 0x1000
+    field public static final int VP9Profile0 = 0; // 0x0
+    field public static final int VP9Profile1 = 1; // 0x1
+    field public static final int VP9Profile2 = 2; // 0x2
+    field public static final int VP9Profile3 = 3; // 0x3
     field public int level;
     field public int profile;
   }
@@ -21752,6 +21842,7 @@
     field public static final java.lang.String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
     field public static final java.lang.String KEY_FRAME_RATE = "frame-rate";
     field public static final java.lang.String KEY_HEIGHT = "height";
+    field public static final java.lang.String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period";
     field public static final java.lang.String KEY_IS_ADTS = "is-adts";
     field public static final java.lang.String KEY_IS_AUTOSELECT = "is-autoselect";
     field public static final java.lang.String KEY_IS_DEFAULT = "is-default";
@@ -22073,9 +22164,11 @@
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.view.Surface getSurface();
+    method public void pause() throws java.lang.IllegalStateException;
     method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
     method public void release();
     method public void reset();
+    method public void resume() throws java.lang.IllegalStateException;
     method public void setAudioChannels(int);
     method public void setAudioEncoder(int) throws java.lang.IllegalStateException;
     method public void setAudioEncodingBitRate(int);
@@ -22157,6 +22250,7 @@
     field public static final int DEFAULT = 0; // 0x0
     field public static final int H263 = 1; // 0x1
     field public static final int H264 = 2; // 0x2
+    field public static final int HEVC = 5; // 0x5
     field public static final int MPEG_4_SP = 3; // 0x3
     field public static final int VP8 = 4; // 0x4
   }
@@ -23113,7 +23207,11 @@
     method public android.media.session.MediaSession.Token getSessionToken();
     method public boolean isConnected();
     method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
+    method public void subscribe(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void unsubscribe(java.lang.String);
+    method public void unsubscribe(java.lang.String, android.os.Bundle);
+    field public static final java.lang.String EXTRA_PAGE = "android.media.browse.extra.PAGE";
+    field public static final java.lang.String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
   }
 
   public static class MediaBrowser.ConnectionCallback {
@@ -23146,7 +23244,9 @@
   public static abstract class MediaBrowser.SubscriptionCallback {
     ctor public MediaBrowser.SubscriptionCallback();
     method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
+    method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>, android.os.Bundle);
     method public void onError(java.lang.String);
+    method public void onError(java.lang.String, android.os.Bundle);
   }
 
 }
@@ -23594,6 +23694,7 @@
     method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
     method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
     method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+    method public static final android.net.Uri buildRecordedProgramUri(long);
     method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
     field public static final java.lang.String AUTHORITY = "android.media.tv";
   }
@@ -23734,6 +23835,40 @@
     field public static final java.lang.String TRAVEL = "TRAVEL";
   }
 
+  public static final class TvContract.RecordedPrograms implements android.media.tv.TvContract.BaseTvColumns {
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    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_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";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+    field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
+    field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
+    field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
+    field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_NUMBER = "season_number";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
+    field public static final android.net.Uri CONTENT_URI;
+  }
+
   public static final class TvContract.WatchedPrograms implements android.media.tv.TvContract.BaseTvColumns {
     field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_DESCRIPTION = "description";
@@ -23782,17 +23917,19 @@
   }
 
   public final class TvInputInfo implements android.os.Parcelable {
+    method public boolean canRecord();
     method public android.content.Intent createSettingsIntent();
     method public android.content.Intent createSetupIntent();
-    method public static android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.hardware.hdmi.HdmiDeviceInfo, java.lang.String, java.lang.String, android.net.Uri) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.hardware.hdmi.HdmiDeviceInfo, java.lang.String, int, android.graphics.drawable.Icon) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.media.tv.TvInputHardwareInfo, java.lang.String, android.net.Uri) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.media.tv.TvInputHardwareInfo, int, android.graphics.drawable.Icon) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static deprecated android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.hardware.hdmi.HdmiDeviceInfo, java.lang.String, java.lang.String, android.net.Uri) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static deprecated android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.hardware.hdmi.HdmiDeviceInfo, java.lang.String, int, android.graphics.drawable.Icon) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static deprecated android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.media.tv.TvInputHardwareInfo, java.lang.String, android.net.Uri) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static deprecated android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.media.tv.TvInputHardwareInfo, int, android.graphics.drawable.Icon) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
     method public android.hardware.hdmi.HdmiDeviceInfo getHdmiDeviceInfo();
     method public java.lang.String getId();
     method public java.lang.String getParentId();
     method public android.content.pm.ServiceInfo getServiceInfo();
+    method public int getTunerCount();
     method public int getType();
     method public boolean isConnectedToHdmiSwitch();
     method public boolean isHardwareInput();
@@ -23816,6 +23953,18 @@
     field public static final int TYPE_VGA = 1005; // 0x3ed
   }
 
+  public static final class TvInputInfo.Builder {
+    ctor public TvInputInfo.Builder(android.content.Context, java.lang.Class<?>);
+    method public android.media.tv.TvInputInfo build() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public android.media.tv.TvInputInfo.Builder setCanRecord(boolean);
+    method public android.media.tv.TvInputInfo.Builder setHdmiDeviceInfo(android.hardware.hdmi.HdmiDeviceInfo);
+    method public android.media.tv.TvInputInfo.Builder setIcon(android.graphics.drawable.Icon);
+    method public android.media.tv.TvInputInfo.Builder setLabel(int);
+    method public android.media.tv.TvInputInfo.Builder setParentId(java.lang.String);
+    method public android.media.tv.TvInputInfo.Builder setTunerCount(int);
+    method public android.media.tv.TvInputInfo.Builder setTvInputHardwareInfo(android.media.tv.TvInputHardwareInfo);
+  }
+
   public static final class TvInputInfo.TvInputSettings {
     method public static java.util.Map<java.lang.String, java.lang.String> getCustomLabels(android.content.Context, int);
     method public static java.util.Set<java.lang.String> getHiddenTvInputIds(android.content.Context, int);
@@ -23827,6 +23976,7 @@
     method public android.media.tv.TvInputManager.Hardware acquireTvInputHardware(int, android.media.tv.TvInputManager.HardwareCallback, android.media.tv.TvInputInfo);
     method public void addBlockedRating(android.media.tv.TvContentRating);
     method public boolean captureFrame(java.lang.String, android.view.Surface, android.media.tv.TvStreamConfig);
+    method public void createRecordingSession(java.lang.String, android.media.tv.TvInputManager.SessionCallback, android.os.Handler);
     method public void createSession(java.lang.String, android.media.tv.TvInputManager.SessionCallback, android.os.Handler);
     method public java.util.List<android.media.tv.TvStreamConfig> getAvailableTvStreamConfigList(java.lang.String);
     method public java.util.List<android.media.tv.TvContentRating> getBlockedRatings();
@@ -23850,6 +24000,10 @@
     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_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
     field public static final int TIME_SHIFT_STATUS_UNAVAILABLE = 2; // 0x2
@@ -23914,16 +24068,19 @@
     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(java.lang.String, android.media.tv.TvInputInfo);
   }
 
   public abstract class TvInputService extends android.app.Service {
     ctor public TvInputService();
     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 android.media.tv.TvInputInfo onHardwareAdded(android.media.tv.TvInputHardwareInfo);
     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 final void setTvInputInfo(java.lang.String, 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";
   }
@@ -23936,6 +24093,21 @@
     method public final boolean onSetSurface(android.view.Surface);
   }
 
+  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 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 onStopRecording();
+  }
+
   public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
     ctor public TvInputService.Session(android.content.Context);
     method public void layoutSurface(int, int, int, int);
@@ -23966,6 +24138,7 @@
     method public long onTimeShiftGetCurrentPosition();
     method public long onTimeShiftGetStartPosition();
     method public void onTimeShiftPause();
+    method public void onTimeShiftPlay(android.net.Uri);
     method public void onTimeShiftResume();
     method public void onTimeShiftSeekTo(long);
     method public void onTimeShiftSetPlaybackParams(android.media.PlaybackParams);
@@ -23977,6 +24150,26 @@
     method public void setOverlayViewEnabled(boolean);
   }
 
+  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 sendAppPrivateCommand(java.lang.String, android.os.Bundle);
+    method public void startRecording();
+    method public void stopRecording();
+  }
+
+  public class TvRecordingClient.RecordingCallback {
+    ctor public TvRecordingClient.RecordingCallback();
+    method public void onConnected();
+    method public void onDisconnected();
+    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);
+  }
+
   public class TvStreamConfig implements android.os.Parcelable {
     method public int describeContents();
     method public int getFlags();
@@ -24059,6 +24252,7 @@
     method public void setZOrderMediaOverlay(boolean);
     method public void setZOrderOnTop(boolean);
     method public void timeShiftPause();
+    method public void timeShiftPlay(java.lang.String, android.net.Uri);
     method public void timeShiftResume();
     method public void timeShiftSeekTo(long);
     method public void timeShiftSetPlaybackParams(android.media.PlaybackParams);
@@ -24137,6 +24331,7 @@
     field public static final int FORMAT_AUDIBLE = 47364; // 0xb904
     field public static final int FORMAT_AVI = 12298; // 0x300a
     field public static final int FORMAT_BMP = 14340; // 0x3804
+    field public static final int FORMAT_DEFINED = 14336; // 0x3800
     field public static final int FORMAT_DNG = 14353; // 0x3811
     field public static final int FORMAT_DPOF = 12294; // 0x3006
     field public static final int FORMAT_EXECUTABLE = 12291; // 0x3003
@@ -24242,6 +24437,7 @@
   }
 
   public class MtpDeviceInfo {
+    method public final int[] getEventsSupported();
     method public final java.lang.String getManufacturer();
     method public final java.lang.String getModel();
     method public final int[] getOperationsSupported();
@@ -24353,6 +24549,7 @@
     method public boolean isActiveNetworkMetered();
     method public boolean isDefaultNetworkActive();
     method public static deprecated boolean isNetworkTypeValid(int);
+    method public boolean isTetheringSupported();
     method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
     method public void registerNetworkCallback(android.net.NetworkRequest, android.app.PendingIntent);
     method public void releaseNetworkRequest(android.app.PendingIntent);
@@ -24365,7 +24562,10 @@
     method public deprecated boolean requestRouteToHost(int, int);
     method public deprecated void setNetworkPreference(int);
     method public static deprecated boolean setProcessDefaultNetwork(android.net.Network);
+    method public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
+    method public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
     method public deprecated int startUsingNetworkFeature(int, java.lang.String);
+    method public void stopTethering(int);
     method public deprecated int stopUsingNetworkFeature(int, java.lang.String);
     method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
     method public void unregisterNetworkCallback(android.app.PendingIntent);
@@ -24387,6 +24587,9 @@
     field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
     field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
     field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
+    field public static final int TETHERING_BLUETOOTH = 2; // 0x2
+    field public static final int TETHERING_USB = 1; // 0x1
+    field public static final int TETHERING_WIFI = 0; // 0x0
     field public static final int TYPE_BLUETOOTH = 7; // 0x7
     field public static final int TYPE_DUMMY = 8; // 0x8
     field public static final int TYPE_ETHERNET = 9; // 0x9
@@ -24413,7 +24616,10 @@
     method public abstract void onNetworkActive();
   }
 
-  public static abstract class ConnectivityManager.RestrictBackgroundStatus implements java.lang.annotation.Annotation {
+  public static abstract class ConnectivityManager.OnStartTetheringCallback {
+    ctor public ConnectivityManager.OnStartTetheringCallback();
+    method public void onTetheringFailed();
+    method public void onTetheringStarted();
   }
 
   public class Credentials {
@@ -25695,6 +25901,7 @@
     method public java.lang.String getAltSubjectMatch();
     method public java.lang.String getAnonymousIdentity();
     method public java.security.cert.X509Certificate getCaCertificate();
+    method public java.security.cert.X509Certificate[] getCaCertificates();
     method public java.security.cert.X509Certificate getClientCertificate();
     method public java.lang.String getDomainSuffixMatch();
     method public int getEapMethod();
@@ -25707,6 +25914,7 @@
     method public void setAltSubjectMatch(java.lang.String);
     method public void setAnonymousIdentity(java.lang.String);
     method public void setCaCertificate(java.security.cert.X509Certificate);
+    method public void setCaCertificates(java.security.cert.X509Certificate[]);
     method public void setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate);
     method public void setDomainSuffixMatch(java.lang.String);
     method public void setEapMethod(int);
@@ -25917,6 +26125,7 @@
     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
@@ -26420,6 +26629,28 @@
     field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
   }
 
+  public abstract class HostNfcFService extends android.app.Service {
+    ctor public HostNfcFService();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract void onDeactivated(int);
+    method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle);
+    method public final void sendResponsePacket(byte[]);
+    field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
+    field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
+    field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service";
+  }
+
+  public final class NfcFCardEmulation {
+    method public boolean disableNfcFForegroundService(android.app.Activity);
+    method public boolean enableNfcFForegroundService(android.app.Activity, android.content.ComponentName);
+    method public static synchronized android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter);
+    method public java.lang.String getNfcid2ForService(android.content.ComponentName);
+    method public java.lang.String getSystemCodeForService(android.content.ComponentName);
+    method public boolean registerSystemCodeForService(android.content.ComponentName, java.lang.String);
+    method public boolean removeSystemCodeForService(android.content.ComponentName);
+    method public boolean setNfcid2ForService(android.content.ComponentName, java.lang.String);
+  }
+
   public abstract class OffHostApduService extends android.app.Service {
     ctor public OffHostApduService();
     method public abstract android.os.IBinder onBind(android.content.Intent);
@@ -29776,6 +30007,14 @@
     method public final synchronized android.os.CountDownTimer start();
   }
 
+  public final class CpuUsageInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getActive();
+    method public long getTotal();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.os.CpuUsageInfo> CREATOR;
+  }
+
   public class DeadObjectException extends android.os.RemoteException {
     ctor public DeadObjectException();
     ctor public DeadObjectException(java.lang.String);
@@ -30028,6 +30267,18 @@
     method public boolean quitSafely();
   }
 
+  public class HardwarePropertiesManager {
+    method public android.os.CpuUsageInfo[] getCpuUsages();
+    method public float[] getDeviceTemperatures(int);
+    method public float[] getFanSpeeds();
+    field public static final int DEVICE_TEMPERATURE_BATTERY = 2; // 0x2
+    field public static final int DEVICE_TEMPERATURE_CPU = 0; // 0x0
+    field public static final int DEVICE_TEMPERATURE_GPU = 1; // 0x1
+  }
+
+  public static abstract class HardwarePropertiesManager.DeviceTemperatureType implements java.lang.annotation.Annotation {
+  }
+
   public abstract interface IBinder {
     method public abstract void dump(java.io.FileDescriptor, java.lang.String[]) throws android.os.RemoteException;
     method public abstract void dumpAsync(java.io.FileDescriptor, java.lang.String[]) throws android.os.RemoteException;
@@ -30400,6 +30651,7 @@
     field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1
     field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
     field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
+    field public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 256; // 0x100
     field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1
     field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0
     field public static final int USER_ACTIVITY_EVENT_TOUCH = 2; // 0x2
@@ -32768,10 +33020,14 @@
 
   public static final class ContactsContract.Intents {
     ctor public ContactsContract.Intents();
+    field public static final java.lang.String ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS = "android.provider.action.VOICE_SEND_MESSAGE_TO_CONTACTS";
     field public static final java.lang.String ATTACH_IMAGE = "com.android.contacts.action.ATTACH_IMAGE";
     field public static final java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
     field public static final java.lang.String EXTRA_CREATE_DESCRIPTION = "com.android.contacts.action.CREATE_DESCRIPTION";
     field public static final java.lang.String EXTRA_FORCE_CREATE = "com.android.contacts.action.FORCE_CREATE";
+    field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
+    field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_NAME = "android.provider.extra.RECIPIENT_CONTACT_NAME";
+    field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_URI = "android.provider.extra.RECIPIENT_CONTACT_URI";
     field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
     field public static final java.lang.String SEARCH_SUGGESTION_CLICKED = "android.provider.Contacts.SEARCH_SUGGESTION_CLICKED";
     field public static final java.lang.String SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED = "android.provider.Contacts.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED";
@@ -33047,6 +33303,7 @@
     method public static android.net.Uri buildRootsUri(java.lang.String);
     method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String);
     method public static android.net.Uri buildTreeDocumentUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri copyDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri);
     method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
@@ -33055,6 +33312,7 @@
     method public static java.lang.String getSearchDocumentsQuery(android.net.Uri);
     method public static java.lang.String getTreeDocumentId(android.net.Uri);
     method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
+    method public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri);
     method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
     field public static final java.lang.String EXTRA_ERROR = "error";
     field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
@@ -34984,6 +35242,7 @@
     method public void getVarV(int, android.renderscript.FieldPacker);
     method protected void invoke(int);
     method protected void invoke(int, android.renderscript.FieldPacker);
+    method protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void setTimeZone(java.lang.String);
     method public void setVar(int, float);
     method public void setVar(int, double);
@@ -35835,9 +36094,11 @@
     method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public android.media.session.MediaSession.Token getSessionToken();
     method public void notifyChildrenChanged(java.lang.String);
+    method public void notifyChildrenChanged(java.lang.String, android.os.Bundle);
     method public android.os.IBinder onBind(android.content.Intent);
     method public abstract android.service.media.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
     method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
+    method public void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>, android.os.Bundle);
     method public void onLoadItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>);
     method public void setSessionToken(android.media.session.MediaSession.Token);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
@@ -35922,6 +36183,7 @@
     field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb
     field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
     field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
+    field public static final int REASON_PACKAGE_SUSPENDED = 15; // 0xf
     field public static final int REASON_TOPIC_BANNED = 14; // 0xe
     field public static final int REASON_USER_STOPPED = 6; // 0x6
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
@@ -36240,6 +36502,7 @@
     method public void setTheme(int);
     method public void show(android.os.Bundle, int);
     method public void startVoiceActivity(android.content.Intent);
+    field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10
     field public static final int SHOW_SOURCE_APPLICATION = 8; // 0x8
     field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4
     field public static final int SHOW_WITH_ASSIST = 1; // 0x1
@@ -36601,6 +36864,8 @@
 
   public abstract class UtteranceProgressListener {
     ctor public UtteranceProgressListener();
+    method public void onAudioAvailable(java.lang.String, byte[]);
+    method public void onBeginSynthesis(java.lang.String, int, int, int);
     method public abstract void onDone(java.lang.String);
     method public abstract deprecated void onError(java.lang.String);
     method public void onError(java.lang.String, int);
@@ -37369,6 +37634,7 @@
     method public static boolean hasProperty(int, int);
     method public boolean hasProperty(int);
     method public static java.lang.String propertiesToString(int);
+    field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
@@ -37520,6 +37786,7 @@
     method public final void setVideoProvider(android.telecom.Connection.VideoProvider);
     method public final void setVideoState(int);
     method public static java.lang.String stateToString(int);
+    field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
@@ -38172,6 +38439,8 @@
 
   public final class CellIdentityGsm implements android.os.Parcelable {
     method public int describeContents();
+    method public int getArfcn();
+    method public int getBsic();
     method public int getCid();
     method public int getLac();
     method public int getMcc();
@@ -38184,6 +38453,7 @@
   public final class CellIdentityLte implements android.os.Parcelable {
     method public int describeContents();
     method public int getCi();
+    method public int getEarfcn();
     method public int getMcc();
     method public int getMnc();
     method public int getPci();
@@ -38199,6 +38469,7 @@
     method public int getMcc();
     method public int getMnc();
     method public int getPsc();
+    method public int getUarfcn();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityWcdma> CREATOR;
   }
@@ -38620,10 +38891,15 @@
     method public int getActiveSubscriptionInfoCountMax();
     method public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int);
     method public java.util.List<android.telephony.SubscriptionInfo> getActiveSubscriptionInfoList();
+    method public static int getDefaultDataSubscriptionId();
+    method public static int getDefaultSmsSubscriptionId();
+    method public static int getDefaultSubscriptionId();
+    method public static int getDefaultVoiceSubscriptionId();
     method public boolean isNetworkRoaming(int);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
     field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
     field public static final int DATA_ROAMING_ENABLE = 1; // 0x1
+    field public static final int INVALID_SUBSCRIPTION_ID = -1; // 0xffffffff
   }
 
   public static class SubscriptionManager.OnSubscriptionsChangedListener {
@@ -38644,6 +38920,7 @@
     method public boolean endCall();
     method public java.util.List<android.telephony.CellInfo> getAllCellInfo();
     method public int getCallState();
+    method public int getCallState(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
     method public java.lang.String getCdmaMdn();
@@ -38656,30 +38933,46 @@
     method public int getDataActivity();
     method public boolean getDataEnabled();
     method public boolean getDataEnabled(int);
+    method public int getDataNetworkType(int);
     method public int getDataState();
     method public java.lang.String getDeviceId();
     method public java.lang.String getDeviceId(int);
     method public java.lang.String getDeviceSoftwareVersion();
     method public java.lang.String getGroupIdLevel1();
+    method public java.lang.String getGroupIdLevel1(int);
     method public java.lang.String getIccSimChallengeResponse(int, java.lang.String);
+    method public java.lang.String getLine1AlphaTag(int);
     method public java.lang.String getLine1Number();
+    method public java.lang.String getLine1Number(int);
     method public java.lang.String getMmsUAProfUrl();
     method public java.lang.String getMmsUserAgent();
     method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
     method public java.lang.String getNetworkCountryIso();
+    method public java.lang.String getNetworkCountryIso(int);
     method public java.lang.String getNetworkOperator();
+    method public java.lang.String getNetworkOperator(int);
     method public java.lang.String getNetworkOperatorName();
+    method public java.lang.String getNetworkOperatorName(int);
     method public int getNetworkType();
+    method public int getNetworkType(int);
     method public int getPhoneCount();
     method public int getPhoneType();
     method public java.lang.String getSimCountryIso();
+    method public java.lang.String getSimCountryIso(int);
     method public java.lang.String getSimOperator();
+    method public java.lang.String getSimOperator(int);
     method public java.lang.String getSimOperatorName();
+    method public java.lang.String getSimOperatorName(int);
     method public java.lang.String getSimSerialNumber();
+    method public java.lang.String getSimSerialNumber(int);
     method public int getSimState();
     method public java.lang.String getSubscriberId();
+    method public java.lang.String getSubscriberId(int);
     method public java.lang.String getVoiceMailAlphaTag();
+    method public java.lang.String getVoiceMailAlphaTag(int);
     method public java.lang.String getVoiceMailNumber();
+    method public java.lang.String getVoiceMailNumber(int);
+    method public int getVoiceNetworkType(int);
     method public android.net.Uri getVoicemailRingtoneUri(android.telecom.PhoneAccountHandle);
     method public boolean handlePinMmi(java.lang.String);
     method public boolean handlePinMmiForSubscriber(int, java.lang.String);
@@ -38694,6 +38987,7 @@
     method public boolean isHearingAidCompatibilitySupported();
     method public boolean isIdle();
     method public boolean isNetworkRoaming();
+    method public boolean isNetworkRoaming(int);
     method public boolean isOffhook();
     method public boolean isRadioOn();
     method public boolean isRinging();
@@ -38709,11 +39003,13 @@
     method public void setDataEnabled(boolean);
     method public void setDataEnabled(int, boolean);
     method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
+    method public boolean setLine1NumberForDisplay(int, java.lang.String, java.lang.String);
     method public boolean setOperatorBrandOverride(java.lang.String);
     method public boolean setPreferredNetworkTypeToGlobal();
     method public boolean setRadio(boolean);
     method public boolean setRadioPower(boolean);
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
+    method public boolean setVoiceMailNumber(int, java.lang.String, java.lang.String);
     method public void silenceRinger();
     method public boolean supplyPin(java.lang.String);
     method public int[] supplyPinReportResult(java.lang.String);
@@ -39674,9 +39970,23 @@
 
   public class Html {
     method public static java.lang.String escapeHtml(java.lang.CharSequence);
-    method public static android.text.Spanned fromHtml(java.lang.String);
-    method public static android.text.Spanned fromHtml(java.lang.String, android.text.Html.ImageGetter, android.text.Html.TagHandler);
-    method public static java.lang.String toHtml(android.text.Spanned);
+    method public static deprecated android.text.Spanned fromHtml(java.lang.String);
+    method public static android.text.Spanned fromHtml(java.lang.String, int);
+    method public static deprecated android.text.Spanned fromHtml(java.lang.String, android.text.Html.ImageGetter, android.text.Html.TagHandler);
+    method public static android.text.Spanned fromHtml(java.lang.String, int, android.text.Html.ImageGetter, android.text.Html.TagHandler);
+    method public static deprecated java.lang.String toHtml(android.text.Spanned);
+    method public static java.lang.String toHtml(android.text.Spanned, int);
+    field public static final int FROM_HTML_MODE_COMPACT = 63; // 0x3f
+    field public static final int FROM_HTML_MODE_LEGACY = 0; // 0x0
+    field public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256; // 0x100
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32; // 0x20
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16; // 0x10
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2; // 0x2
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8; // 0x8
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4; // 0x4
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1; // 0x1
+    field public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0; // 0x0
+    field public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1; // 0x1
   }
 
   public static abstract interface Html.ImageGetter {
@@ -50863,7 +51173,6 @@
     method public boolean setReadable(boolean);
     method public boolean setWritable(boolean, boolean);
     method public boolean setWritable(boolean);
-    method public java.nio.file.Path toPath();
     method public java.net.URI toURI();
     method public deprecated java.net.URL toURL() throws java.net.MalformedURLException;
     field public static final java.lang.String pathSeparator;
@@ -52416,6 +52725,9 @@
     field public static final java.lang.Class<java.lang.Float> TYPE;
   }
 
+  public abstract class FunctionalInterface implements java.lang.annotation.Annotation {
+  }
+
   public class IllegalAccessError extends java.lang.IncompatibleClassChangeError {
     ctor public IllegalAccessError();
     ctor public IllegalAccessError(java.lang.String);
@@ -53545,6 +53857,7 @@
     method public java.lang.Object invoke(java.lang.Object, java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
     method public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>);
     method public boolean isBridge();
+    method public boolean isDefault();
     method public boolean isSynthetic();
     method public boolean isVarArgs();
     method public java.lang.String toGenericString();
@@ -54958,25 +55271,6 @@
     ctor public AsynchronousCloseException();
   }
 
-  public abstract class AsynchronousFileChannel implements java.nio.channels.AsynchronousChannel {
-    ctor protected AsynchronousFileChannel();
-    method public abstract void force(boolean) throws java.io.IOException;
-    method public abstract void lock(long, long, boolean, A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock, ? super A>);
-    method public final void lock(A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock, ? super A>);
-    method public abstract java.util.concurrent.Future<java.nio.channels.FileLock> lock(long, long, boolean);
-    method public final java.util.concurrent.Future<java.nio.channels.FileLock> lock();
-    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public abstract void read(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer, long);
-    method public abstract long size() throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousFileChannel truncate(long) throws java.io.IOException;
-    method public abstract java.nio.channels.FileLock tryLock(long, long, boolean) throws java.io.IOException;
-    method public final java.nio.channels.FileLock tryLock() throws java.io.IOException;
-    method public abstract void write(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer, long);
-  }
-
   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>);
@@ -55085,8 +55379,6 @@
     method public abstract java.nio.channels.FileLock lock(long, long, boolean) throws java.io.IOException;
     method public final java.nio.channels.FileLock lock() throws java.io.IOException;
     method public abstract java.nio.MappedByteBuffer map(java.nio.channels.FileChannel.MapMode, long, long) throws java.io.IOException;
-    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
     method public abstract long position() throws java.io.IOException;
     method public abstract java.nio.channels.FileChannel position(long) throws java.io.IOException;
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
@@ -55113,7 +55405,6 @@
 
   public abstract class FileLock implements java.lang.AutoCloseable {
     ctor protected FileLock(java.nio.channels.FileChannel, long, long, boolean);
-    ctor protected FileLock(java.nio.channels.AsynchronousFileChannel, long, long, boolean);
     method public java.nio.channels.Channel acquiredBy();
     method public final java.nio.channels.FileChannel channel();
     method public final void close() throws java.io.IOException;
@@ -55563,592 +55854,6 @@
 
 }
 
-package java.nio.file {
-
-  public class AccessDeniedException extends java.nio.file.FileSystemException {
-    ctor public AccessDeniedException(java.lang.String);
-    ctor public AccessDeniedException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public final class AccessMode extends java.lang.Enum {
-    method public static java.nio.file.AccessMode valueOf(java.lang.String);
-    method public static final java.nio.file.AccessMode[] values();
-    enum_constant public static final java.nio.file.AccessMode EXECUTE;
-    enum_constant public static final java.nio.file.AccessMode READ;
-    enum_constant public static final java.nio.file.AccessMode WRITE;
-  }
-
-  public class AtomicMoveNotSupportedException extends java.nio.file.FileSystemException {
-    ctor public AtomicMoveNotSupportedException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public class ClosedDirectoryStreamException extends java.lang.IllegalStateException {
-    ctor public ClosedDirectoryStreamException();
-  }
-
-  public class ClosedFileSystemException extends java.lang.IllegalStateException {
-    ctor public ClosedFileSystemException();
-  }
-
-  public class ClosedWatchServiceException extends java.lang.IllegalStateException {
-    ctor public ClosedWatchServiceException();
-  }
-
-  public abstract interface CopyOption {
-  }
-
-  public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
-    ctor public DirectoryIteratorException(java.io.IOException);
-  }
-
-  public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
-    ctor public DirectoryNotEmptyException(java.lang.String);
-  }
-
-  public abstract interface DirectoryStream implements java.io.Closeable java.lang.Iterable {
-    method public abstract java.util.Iterator<T> iterator();
-  }
-
-  public static abstract interface DirectoryStream.Filter {
-    method public abstract boolean accept(T) throws java.io.IOException;
-  }
-
-  public class FileAlreadyExistsException extends java.nio.file.FileSystemException {
-    ctor public FileAlreadyExistsException(java.lang.String);
-    ctor public FileAlreadyExistsException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public abstract class FileStore {
-    ctor protected FileStore();
-    method public abstract java.lang.Object getAttribute(java.lang.String) throws java.io.IOException;
-    method public abstract V getFileStoreAttributeView(java.lang.Class<V>);
-    method public abstract long getTotalSpace() throws java.io.IOException;
-    method public abstract long getUnallocatedSpace() throws java.io.IOException;
-    method public abstract long getUsableSpace() throws java.io.IOException;
-    method public abstract boolean isReadOnly();
-    method public abstract java.lang.String name();
-    method public abstract boolean supportsFileAttributeView(java.lang.Class<? extends java.nio.file.attribute.FileAttributeView>);
-    method public abstract boolean supportsFileAttributeView(java.lang.String);
-    method public abstract java.lang.String type();
-  }
-
-  public abstract class FileSystem implements java.io.Closeable {
-    ctor protected FileSystem();
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.lang.Iterable<java.nio.file.FileStore> getFileStores();
-    method public abstract java.nio.file.Path getPath(java.lang.String, java.lang.String...);
-    method public abstract java.nio.file.PathMatcher getPathMatcher(java.lang.String);
-    method public abstract java.lang.Iterable<java.nio.file.Path> getRootDirectories();
-    method public abstract java.lang.String getSeparator();
-    method public abstract java.nio.file.attribute.UserPrincipalLookupService getUserPrincipalLookupService();
-    method public abstract boolean isOpen();
-    method public abstract boolean isReadOnly();
-    method public abstract java.nio.file.WatchService newWatchService() throws java.io.IOException;
-    method public abstract java.nio.file.spi.FileSystemProvider provider();
-    method public abstract java.util.Set<java.lang.String> supportedFileAttributeViews();
-  }
-
-  public class FileSystemAlreadyExistsException extends java.lang.RuntimeException {
-    ctor public FileSystemAlreadyExistsException();
-    ctor public FileSystemAlreadyExistsException(java.lang.String);
-  }
-
-  public class FileSystemException extends java.io.IOException {
-    ctor public FileSystemException(java.lang.String);
-    ctor public FileSystemException(java.lang.String, java.lang.String, java.lang.String);
-    method public java.lang.String getFile();
-    method public java.lang.String getOtherFile();
-    method public java.lang.String getReason();
-  }
-
-  public class FileSystemLoopException extends java.nio.file.FileSystemException {
-    ctor public FileSystemLoopException(java.lang.String);
-  }
-
-  public class FileSystemNotFoundException extends java.lang.RuntimeException {
-    ctor public FileSystemNotFoundException();
-    ctor public FileSystemNotFoundException(java.lang.String);
-  }
-
-  public final class FileSystems {
-    method public static java.nio.file.FileSystem getDefault();
-    method public static java.nio.file.FileSystem getFileSystem(java.net.URI);
-    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>) throws java.io.IOException;
-    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>, java.lang.ClassLoader) throws java.io.IOException;
-    method public static java.nio.file.FileSystem newFileSystem(java.nio.file.Path, java.lang.ClassLoader) throws java.io.IOException;
-  }
-
-  public final class FileVisitOption extends java.lang.Enum {
-    method public static java.nio.file.FileVisitOption valueOf(java.lang.String);
-    method public static final java.nio.file.FileVisitOption[] values();
-    enum_constant public static final java.nio.file.FileVisitOption FOLLOW_LINKS;
-  }
-
-  public final class FileVisitResult extends java.lang.Enum {
-    method public static java.nio.file.FileVisitResult valueOf(java.lang.String);
-    method public static final java.nio.file.FileVisitResult[] values();
-    enum_constant public static final java.nio.file.FileVisitResult CONTINUE;
-    enum_constant public static final java.nio.file.FileVisitResult SKIP_SIBLINGS;
-    enum_constant public static final java.nio.file.FileVisitResult SKIP_SUBTREE;
-    enum_constant public static final java.nio.file.FileVisitResult TERMINATE;
-  }
-
-  public abstract interface FileVisitor {
-    method public abstract java.nio.file.FileVisitResult postVisitDirectory(T, java.io.IOException) throws java.io.IOException;
-    method public abstract java.nio.file.FileVisitResult preVisitDirectory(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public abstract java.nio.file.FileVisitResult visitFile(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public abstract java.nio.file.FileVisitResult visitFileFailed(T, java.io.IOException) throws java.io.IOException;
-  }
-
-  public final class Files {
-    method public static java.nio.file.Path copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static long copy(java.io.InputStream, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static long copy(java.nio.file.Path, java.io.OutputStream) throws java.io.IOException;
-    method public static java.nio.file.Path createDirectories(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createFile(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempDirectory(java.nio.file.Path, java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempDirectory(java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempFile(java.nio.file.Path, java.lang.String, java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempFile(java.lang.String, java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static void delete(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean exists(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static java.lang.Object getAttribute(java.nio.file.Path, java.lang.String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static V getFileAttributeView(java.nio.file.Path, java.lang.Class<V>, java.nio.file.LinkOption...);
-    method public static java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.attribute.FileTime getLastModifiedTime(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.attribute.UserPrincipal getOwner(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> getPosixFilePermissions(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static boolean isDirectory(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static boolean isExecutable(java.nio.file.Path);
-    method public static boolean isHidden(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean isReadable(java.nio.file.Path);
-    method public static boolean isRegularFile(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public static boolean isSymbolicLink(java.nio.file.Path);
-    method public static boolean isWritable(java.nio.file.Path);
-    method public static java.nio.file.Path move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static java.io.BufferedReader newBufferedReader(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
-    method public static java.io.BufferedWriter newBufferedWriter(java.nio.file.Path, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.lang.String) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static boolean notExists(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static java.lang.String probeContentType(java.nio.file.Path) throws java.io.IOException;
-    method public static byte[] readAllBytes(java.nio.file.Path) throws java.io.IOException;
-    method public static java.util.List<java.lang.String> readAllLines(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
-    method public static A readAttributes(java.nio.file.Path, java.lang.Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.util.Map<java.lang.String, java.lang.Object> readAttributes(java.nio.file.Path, java.lang.String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path setAttribute(java.nio.file.Path, java.lang.String, java.lang.Object, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.Path setLastModifiedTime(java.nio.file.Path, java.nio.file.attribute.FileTime) throws java.io.IOException;
-    method public static java.nio.file.Path setOwner(java.nio.file.Path, java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
-    method public static java.nio.file.Path setPosixFilePermissions(java.nio.file.Path, java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
-    method public static long size(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.util.Set<java.nio.file.FileVisitOption>, int, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.nio.file.Path write(java.nio.file.Path, byte[], java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.file.Path write(java.nio.file.Path, java.lang.Iterable<? extends java.lang.CharSequence>, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
-  }
-
-  public class InvalidPathException extends java.lang.IllegalArgumentException {
-    ctor public InvalidPathException(java.lang.String, java.lang.String, int);
-    ctor public InvalidPathException(java.lang.String, java.lang.String);
-    method public int getIndex();
-    method public java.lang.String getInput();
-    method public java.lang.String getReason();
-  }
-
-  public final class LinkOption extends java.lang.Enum implements java.nio.file.CopyOption java.nio.file.OpenOption {
-    method public static java.nio.file.LinkOption valueOf(java.lang.String);
-    method public static final java.nio.file.LinkOption[] values();
-    enum_constant public static final java.nio.file.LinkOption NOFOLLOW_LINKS;
-  }
-
-  public final class LinkPermission extends java.security.BasicPermission {
-    ctor public LinkPermission(java.lang.String);
-    ctor public LinkPermission(java.lang.String, java.lang.String);
-  }
-
-  public class NoSuchFileException extends java.nio.file.FileSystemException {
-    ctor public NoSuchFileException(java.lang.String);
-    ctor public NoSuchFileException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public class NotDirectoryException extends java.nio.file.FileSystemException {
-    ctor public NotDirectoryException(java.lang.String);
-  }
-
-  public class NotLinkException extends java.nio.file.FileSystemException {
-    ctor public NotLinkException(java.lang.String);
-    ctor public NotLinkException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public abstract interface OpenOption {
-  }
-
-  public abstract interface Path implements java.lang.Comparable java.lang.Iterable java.nio.file.Watchable {
-    method public abstract int compareTo(java.nio.file.Path);
-    method public abstract boolean endsWith(java.nio.file.Path);
-    method public abstract boolean endsWith(java.lang.String);
-    method public abstract boolean equals(java.lang.Object);
-    method public abstract java.nio.file.Path getFileName();
-    method public abstract java.nio.file.FileSystem getFileSystem();
-    method public abstract java.nio.file.Path getName(int);
-    method public abstract int getNameCount();
-    method public abstract java.nio.file.Path getParent();
-    method public abstract java.nio.file.Path getRoot();
-    method public abstract int hashCode();
-    method public abstract boolean isAbsolute();
-    method public abstract java.util.Iterator<java.nio.file.Path> iterator();
-    method public abstract java.nio.file.Path normalize();
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>[], java.nio.file.WatchEvent.Modifier...) throws java.io.IOException;
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.Path relativize(java.nio.file.Path);
-    method public abstract java.nio.file.Path resolve(java.nio.file.Path);
-    method public abstract java.nio.file.Path resolve(java.lang.String);
-    method public abstract java.nio.file.Path resolveSibling(java.nio.file.Path);
-    method public abstract java.nio.file.Path resolveSibling(java.lang.String);
-    method public abstract boolean startsWith(java.nio.file.Path);
-    method public abstract boolean startsWith(java.lang.String);
-    method public abstract java.nio.file.Path subpath(int, int);
-    method public abstract java.nio.file.Path toAbsolutePath();
-    method public abstract java.io.File toFile();
-    method public abstract java.nio.file.Path toRealPath(java.nio.file.LinkOption...) throws java.io.IOException;
-    method public abstract java.lang.String toString();
-    method public abstract java.net.URI toUri();
-  }
-
-  public abstract interface PathMatcher {
-    method public abstract boolean matches(java.nio.file.Path);
-  }
-
-  public final class Paths {
-    method public static java.nio.file.Path get(java.lang.String, java.lang.String...);
-    method public static java.nio.file.Path get(java.net.URI);
-  }
-
-  public class ProviderMismatchException extends java.lang.IllegalArgumentException {
-    ctor public ProviderMismatchException();
-    ctor public ProviderMismatchException(java.lang.String);
-  }
-
-  public class ProviderNotFoundException extends java.lang.RuntimeException {
-    ctor public ProviderNotFoundException();
-    ctor public ProviderNotFoundException(java.lang.String);
-  }
-
-  public class ReadOnlyFileSystemException extends java.lang.UnsupportedOperationException {
-    ctor public ReadOnlyFileSystemException();
-  }
-
-  public abstract interface SecureDirectoryStream implements java.nio.file.DirectoryStream {
-    method public abstract void deleteDirectory(T) throws java.io.IOException;
-    method public abstract void deleteFile(T) throws java.io.IOException;
-    method public abstract V getFileAttributeView(java.lang.Class<V>);
-    method public abstract V getFileAttributeView(T, java.lang.Class<V>, java.nio.file.LinkOption...);
-    method public abstract void move(T, java.nio.file.SecureDirectoryStream<T>, T) throws java.io.IOException;
-    method public abstract java.nio.channels.SeekableByteChannel newByteChannel(T, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.SecureDirectoryStream<T> newDirectoryStream(T, java.nio.file.LinkOption...) throws java.io.IOException;
-  }
-
-  public final class StandardCopyOption extends java.lang.Enum implements java.nio.file.CopyOption {
-    method public static java.nio.file.StandardCopyOption valueOf(java.lang.String);
-    method public static final java.nio.file.StandardCopyOption[] values();
-    enum_constant public static final java.nio.file.StandardCopyOption ATOMIC_MOVE;
-    enum_constant public static final java.nio.file.StandardCopyOption COPY_ATTRIBUTES;
-    enum_constant public static final java.nio.file.StandardCopyOption REPLACE_EXISTING;
-  }
-
-  public final class StandardOpenOption extends java.lang.Enum implements java.nio.file.OpenOption {
-    method public static java.nio.file.StandardOpenOption valueOf(java.lang.String);
-    method public static final java.nio.file.StandardOpenOption[] values();
-    enum_constant public static final java.nio.file.StandardOpenOption APPEND;
-    enum_constant public static final java.nio.file.StandardOpenOption CREATE;
-    enum_constant public static final java.nio.file.StandardOpenOption CREATE_NEW;
-    enum_constant public static final java.nio.file.StandardOpenOption DELETE_ON_CLOSE;
-    enum_constant public static final java.nio.file.StandardOpenOption DSYNC;
-    enum_constant public static final java.nio.file.StandardOpenOption READ;
-    enum_constant public static final java.nio.file.StandardOpenOption SPARSE;
-    enum_constant public static final java.nio.file.StandardOpenOption SYNC;
-    enum_constant public static final java.nio.file.StandardOpenOption TRUNCATE_EXISTING;
-    enum_constant public static final java.nio.file.StandardOpenOption WRITE;
-  }
-
-  public final class StandardWatchEventKinds {
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_CREATE;
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_DELETE;
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_MODIFY;
-    field public static final java.nio.file.WatchEvent.Kind<java.lang.Object> OVERFLOW;
-  }
-
-  public abstract interface WatchEvent {
-    method public abstract T context();
-    method public abstract int count();
-    method public abstract java.nio.file.WatchEvent.Kind<T> kind();
-  }
-
-  public static abstract interface WatchEvent.Kind {
-    method public abstract java.lang.String name();
-    method public abstract java.lang.Class<T> type();
-  }
-
-  public static abstract interface WatchEvent.Modifier {
-    method public abstract java.lang.String name();
-  }
-
-  public abstract interface WatchKey {
-    method public abstract void cancel();
-    method public abstract boolean isValid();
-    method public abstract java.util.List<java.nio.file.WatchEvent<?>> pollEvents();
-    method public abstract boolean reset();
-    method public abstract java.nio.file.Watchable watchable();
-  }
-
-  public abstract interface WatchService implements java.io.Closeable {
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.nio.file.WatchKey poll();
-    method public abstract java.nio.file.WatchKey poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public abstract java.nio.file.WatchKey take() throws java.lang.InterruptedException;
-  }
-
-  public abstract interface Watchable {
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>[], java.nio.file.WatchEvent.Modifier...) throws java.io.IOException;
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>...) throws java.io.IOException;
-  }
-
-}
-
-package java.nio.file.attribute {
-
-  public final class AclEntry {
-    method public java.util.Set<java.nio.file.attribute.AclEntryFlag> flags();
-    method public static java.nio.file.attribute.AclEntry.Builder newBuilder();
-    method public static java.nio.file.attribute.AclEntry.Builder newBuilder(java.nio.file.attribute.AclEntry);
-    method public java.util.Set<java.nio.file.attribute.AclEntryPermission> permissions();
-    method public java.nio.file.attribute.UserPrincipal principal();
-    method public java.nio.file.attribute.AclEntryType type();
-  }
-
-  public static final class AclEntry.Builder {
-    method public java.nio.file.attribute.AclEntry build();
-    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.util.Set<java.nio.file.attribute.AclEntryFlag>);
-    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.nio.file.attribute.AclEntryFlag...);
-    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.util.Set<java.nio.file.attribute.AclEntryPermission>);
-    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.nio.file.attribute.AclEntryPermission...);
-    method public java.nio.file.attribute.AclEntry.Builder setPrincipal(java.nio.file.attribute.UserPrincipal);
-    method public java.nio.file.attribute.AclEntry.Builder setType(java.nio.file.attribute.AclEntryType);
-  }
-
-  public final class AclEntryFlag extends java.lang.Enum {
-    method public static java.nio.file.attribute.AclEntryFlag valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.AclEntryFlag[] values();
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag DIRECTORY_INHERIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag FILE_INHERIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag INHERIT_ONLY;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag NO_PROPAGATE_INHERIT;
-  }
-
-  public final class AclEntryPermission extends java.lang.Enum {
-    method public static java.nio.file.attribute.AclEntryPermission valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.AclEntryPermission[] values();
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission APPEND_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE_CHILD;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission EXECUTE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ACL;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ATTRIBUTES;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_NAMED_ATTRS;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission SYNCHRONIZE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ACL;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ATTRIBUTES;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_NAMED_ATTRS;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_OWNER;
-    field public static final java.nio.file.attribute.AclEntryPermission ADD_FILE;
-    field public static final java.nio.file.attribute.AclEntryPermission ADD_SUBDIRECTORY;
-    field public static final java.nio.file.attribute.AclEntryPermission LIST_DIRECTORY;
-  }
-
-  public final class AclEntryType extends java.lang.Enum {
-    method public static java.nio.file.attribute.AclEntryType valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.AclEntryType[] values();
-    enum_constant public static final java.nio.file.attribute.AclEntryType ALARM;
-    enum_constant public static final java.nio.file.attribute.AclEntryType ALLOW;
-    enum_constant public static final java.nio.file.attribute.AclEntryType AUDIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryType DENY;
-  }
-
-  public abstract interface AclFileAttributeView implements java.nio.file.attribute.FileOwnerAttributeView {
-    method public abstract java.util.List<java.nio.file.attribute.AclEntry> getAcl() throws java.io.IOException;
-    method public abstract java.lang.String name();
-    method public abstract void setAcl(java.util.List<java.nio.file.attribute.AclEntry>) throws java.io.IOException;
-  }
-
-  public abstract interface AttributeView {
-    method public abstract java.lang.String name();
-  }
-
-  public abstract interface BasicFileAttributeView implements java.nio.file.attribute.FileAttributeView {
-    method public abstract java.lang.String name();
-    method public abstract java.nio.file.attribute.BasicFileAttributes readAttributes() throws java.io.IOException;
-    method public abstract void setTimes(java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime) throws java.io.IOException;
-  }
-
-  public abstract interface BasicFileAttributes {
-    method public abstract java.nio.file.attribute.FileTime creationTime();
-    method public abstract java.lang.Object fileKey();
-    method public abstract boolean isDirectory();
-    method public abstract boolean isOther();
-    method public abstract boolean isRegularFile();
-    method public abstract boolean isSymbolicLink();
-    method public abstract java.nio.file.attribute.FileTime lastAccessTime();
-    method public abstract java.nio.file.attribute.FileTime lastModifiedTime();
-    method public abstract long size();
-  }
-
-  public abstract interface DosFileAttributeView implements java.nio.file.attribute.BasicFileAttributeView {
-    method public abstract java.lang.String name();
-    method public abstract java.nio.file.attribute.DosFileAttributes readAttributes() throws java.io.IOException;
-    method public abstract void setArchive(boolean) throws java.io.IOException;
-    method public abstract void setHidden(boolean) throws java.io.IOException;
-    method public abstract void setReadOnly(boolean) throws java.io.IOException;
-    method public abstract void setSystem(boolean) throws java.io.IOException;
-  }
-
-  public abstract interface DosFileAttributes implements java.nio.file.attribute.BasicFileAttributes {
-    method public abstract boolean isArchive();
-    method public abstract boolean isHidden();
-    method public abstract boolean isReadOnly();
-    method public abstract boolean isSystem();
-  }
-
-  public abstract interface FileAttribute {
-    method public abstract java.lang.String name();
-    method public abstract T value();
-  }
-
-  public abstract interface FileAttributeView implements java.nio.file.attribute.AttributeView {
-  }
-
-  public abstract interface FileOwnerAttributeView implements java.nio.file.attribute.FileAttributeView {
-    method public abstract java.nio.file.attribute.UserPrincipal getOwner() throws java.io.IOException;
-    method public abstract java.lang.String name();
-    method public abstract void setOwner(java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
-  }
-
-  public abstract interface FileStoreAttributeView implements java.nio.file.attribute.AttributeView {
-  }
-
-  public final class FileTime implements java.lang.Comparable {
-    method public int compareTo(java.nio.file.attribute.FileTime);
-    method public static java.nio.file.attribute.FileTime from(long, java.util.concurrent.TimeUnit);
-    method public static java.nio.file.attribute.FileTime fromMillis(long);
-    method public long to(java.util.concurrent.TimeUnit);
-    method public long toMillis();
-  }
-
-  public abstract interface GroupPrincipal implements java.nio.file.attribute.UserPrincipal {
-  }
-
-  public abstract interface PosixFileAttributeView implements java.nio.file.attribute.BasicFileAttributeView java.nio.file.attribute.FileOwnerAttributeView {
-    method public abstract java.lang.String name();
-    method public abstract java.nio.file.attribute.PosixFileAttributes readAttributes() throws java.io.IOException;
-    method public abstract void setGroup(java.nio.file.attribute.GroupPrincipal) throws java.io.IOException;
-    method public abstract void setPermissions(java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
-  }
-
-  public abstract interface PosixFileAttributes implements java.nio.file.attribute.BasicFileAttributes {
-    method public abstract java.nio.file.attribute.GroupPrincipal group();
-    method public abstract java.nio.file.attribute.UserPrincipal owner();
-    method public abstract java.util.Set<java.nio.file.attribute.PosixFilePermission> permissions();
-  }
-
-  public final class PosixFilePermission extends java.lang.Enum {
-    method public static java.nio.file.attribute.PosixFilePermission valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.PosixFilePermission[] values();
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_WRITE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_WRITE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_WRITE;
-  }
-
-  public final class PosixFilePermissions {
-    method public static java.nio.file.attribute.FileAttribute<java.util.Set<java.nio.file.attribute.PosixFilePermission>> asFileAttribute(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
-    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> fromString(java.lang.String);
-    method public static java.lang.String toString(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
-  }
-
-  public abstract interface UserPrincipal implements java.security.Principal {
-  }
-
-  public abstract class UserPrincipalLookupService {
-    ctor protected UserPrincipalLookupService();
-    method public abstract java.nio.file.attribute.GroupPrincipal lookupPrincipalByGroupName(java.lang.String) throws java.io.IOException;
-    method public abstract java.nio.file.attribute.UserPrincipal lookupPrincipalByName(java.lang.String) throws java.io.IOException;
-  }
-
-  public class UserPrincipalNotFoundException extends java.io.IOException {
-    ctor public UserPrincipalNotFoundException(java.lang.String);
-    method public java.lang.String getName();
-  }
-
-}
-
-package java.nio.file.spi {
-
-  public abstract class FileSystemProvider {
-    ctor protected FileSystemProvider();
-    method public abstract void checkAccess(java.nio.file.Path, java.nio.file.AccessMode...) throws java.io.IOException;
-    method public abstract void copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public abstract void createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public void createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public void createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract void delete(java.nio.file.Path) throws java.io.IOException;
-    method public boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
-    method public abstract V getFileAttributeView(java.nio.file.Path, java.lang.Class<V>, java.nio.file.LinkOption...);
-    method public abstract java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
-    method public abstract java.nio.file.FileSystem getFileSystem(java.net.URI);
-    method public abstract java.nio.file.Path getPath(java.net.URI);
-    method public abstract java.lang.String getScheme();
-    method public static java.util.List<java.nio.file.spi.FileSystemProvider> installedProviders();
-    method public abstract boolean isHidden(java.nio.file.Path) throws java.io.IOException;
-    method public abstract boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public abstract void move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public java.nio.channels.AsynchronousFileChannel newAsynchronousFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
-    method public java.nio.channels.FileChannel newFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>) throws java.io.IOException;
-    method public java.nio.file.FileSystem newFileSystem(java.nio.file.Path, java.util.Map<java.lang.String, ?>) throws java.io.IOException;
-    method public java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public abstract A readAttributes(java.nio.file.Path, java.lang.Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public abstract java.util.Map<java.lang.String, java.lang.Object> readAttributes(java.nio.file.Path, java.lang.String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
-    method public abstract void setAttribute(java.nio.file.Path, java.lang.String, java.lang.Object, java.nio.file.LinkOption...) throws java.io.IOException;
-  }
-
-  public abstract class FileTypeDetector {
-    ctor protected FileTypeDetector();
-    method public abstract java.lang.String probeContentType(java.nio.file.Path) throws java.io.IOException;
-  }
-
-}
-
 package java.security {
 
   public final class AccessControlContext {
@@ -60745,8 +60450,6 @@
     ctor public Scanner(java.io.InputStream, java.lang.String);
     ctor public Scanner(java.io.File) throws java.io.FileNotFoundException;
     ctor public Scanner(java.io.File, java.lang.String) throws java.io.FileNotFoundException;
-    ctor public Scanner(java.nio.file.Path) throws java.io.IOException;
-    ctor public Scanner(java.nio.file.Path, java.lang.String) throws java.io.IOException;
     ctor public Scanner(java.lang.String);
     ctor public Scanner(java.nio.channels.ReadableByteChannel);
     ctor public Scanner(java.nio.channels.ReadableByteChannel, java.lang.String);
diff --git a/api/test-current.txt b/api/test-current.txt
index d05c1e4..c87da04 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -67,7 +67,7 @@
     field public static final java.lang.String DUMP = "android.permission.DUMP";
     field public static final java.lang.String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
     field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
-    field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
+    field public static final deprecated java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
     field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
     field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
     field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
@@ -1183,6 +1183,7 @@
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsAssist = 16844016; // 0x10104f0
     field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
+    field public static final int supportsLocalInteraction = 16844048; // 0x1010510
     field public static final int supportsPictureInPicture = 16844024; // 0x10104f8
     field public static final int supportsRtl = 16843695; // 0x10103af
     field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
@@ -3436,6 +3437,7 @@
     method public boolean isDestroyed();
     method public boolean isFinishing();
     method public boolean isImmersive();
+    method public boolean isLocalVoiceInteractionSupported();
     method public boolean isTaskRoot();
     method public boolean isVoiceInteraction();
     method public boolean isVoiceInteractionRoot();
@@ -3477,6 +3479,8 @@
     method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
     method public boolean onKeyShortcut(int, android.view.KeyEvent);
     method public boolean onKeyUp(int, android.view.KeyEvent);
+    method public void onLocalVoiceInteractionStarted();
+    method public void onLocalVoiceInteractionStopped();
     method public void onLowMemory();
     method public boolean onMenuItemSelected(int, android.view.MenuItem);
     method public boolean onMenuOpened(int, android.view.Menu);
@@ -3591,12 +3595,14 @@
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSenderFromChild(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSenderFromChild(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+    method public void startLocalVoiceInteraction(android.os.Bundle);
     method public void startLockTask();
     method public deprecated void startManagingCursor(android.database.Cursor);
     method public boolean startNextMatchingActivity(android.content.Intent);
     method public boolean startNextMatchingActivity(android.content.Intent, android.os.Bundle);
     method public void startPostponedEnterTransition();
     method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
+    method public void stopLocalVoiceInteraction();
     method public void stopLockTask();
     method public deprecated void stopManagingCursor(android.database.Cursor);
     method public void takeKeyEvents(boolean);
@@ -3670,9 +3676,6 @@
     method public void startActivity(android.content.Context, android.content.Intent, android.os.Bundle);
   }
 
-  public static abstract class ActivityManager.BugreportMode implements java.lang.annotation.Annotation {
-  }
-
   public static class ActivityManager.MemoryInfo implements android.os.Parcelable {
     ctor public ActivityManager.MemoryInfo();
     method public int describeContents();
@@ -5688,10 +5691,13 @@
     method public android.graphics.drawable.Drawable peekFastDrawable();
     method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
     method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
-    method public void setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean, int) throws java.io.IOException;
     method public void setResource(int) throws java.io.IOException;
+    method public int setResource(int, int) throws java.io.IOException;
     method public void setStream(java.io.InputStream) throws java.io.IOException;
-    method public void setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+    method public int setStream(java.io.InputStream, android.graphics.Rect, boolean, int) throws java.io.IOException;
     method public void setWallpaperOffsetSteps(float, float);
     method public void setWallpaperOffsets(android.os.IBinder, float, float);
     method public void suggestDesiredDimensions(int, int);
@@ -5702,6 +5708,8 @@
     field public static final java.lang.String COMMAND_SECONDARY_TAP = "android.wallpaper.secondaryTap";
     field public static final java.lang.String COMMAND_TAP = "android.wallpaper.tap";
     field public static final java.lang.String EXTRA_LIVE_WALLPAPER_COMPONENT = "android.service.wallpaper.extra.LIVE_WALLPAPER_COMPONENT";
+    field public static final int FLAG_SET_LOCK = 2; // 0x2
+    field public static final int FLAG_SET_SYSTEM = 1; // 0x1
     field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
   }
 
@@ -5774,9 +5782,6 @@
     field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
   }
 
-  public static abstract class DeviceAdminReceiver.BugreportFailureCode implements java.lang.annotation.Annotation {
-  }
-
   public class DevicePolicyManager {
     method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
     method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5787,6 +5792,7 @@
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
     method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
     method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
+    method public android.os.UserHandle createAndManageUser(android.content.ComponentName, java.lang.String, android.content.ComponentName, android.os.PersistableBundle, int);
     method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
     method public void enableSystemApp(android.content.ComponentName, java.lang.String);
     method public int enableSystemApp(android.content.ComponentName, android.content.Intent);
@@ -5979,6 +5985,7 @@
     field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
     field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
     field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
+    field public static final int SKIP_SETUP_WIZARD = 1; // 0x1
     field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
     field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
   }
@@ -6100,6 +6107,7 @@
     method public void onCreate();
     method public void onDestroy();
     method public void onFullBackup(android.app.backup.FullBackupDataOutput) throws java.io.IOException;
+    method public void onQuotaExceeded(long, long);
     method public abstract void onRestore(android.app.backup.BackupDataInput, int, android.os.ParcelFileDescriptor) throws java.io.IOException;
     method public void onRestoreFile(android.os.ParcelFileDescriptor, long, java.io.File, int, long, long) throws java.io.IOException;
     method public void onRestoreFinished();
@@ -6188,6 +6196,7 @@
     method public long getMinLatencyMillis();
     method public int getNetworkType();
     method public android.content.ComponentName getService();
+    method public android.app.job.JobInfo.TriggerContentUri[] getTriggerContentUris();
     method public boolean isPeriodic();
     method public boolean isPersisted();
     method public boolean isRequireCharging();
@@ -6207,6 +6216,7 @@
 
   public static final class JobInfo.Builder {
     ctor public JobInfo.Builder(int, android.content.ComponentName);
+    method public android.app.job.JobInfo.Builder addTriggerContentUri(android.app.job.JobInfo.TriggerContentUri);
     method public android.app.job.JobInfo build();
     method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int);
     method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle);
@@ -6220,10 +6230,22 @@
     method public android.app.job.JobInfo.Builder setRequiresDeviceIdle(boolean);
   }
 
+  public static final class JobInfo.TriggerContentUri implements android.os.Parcelable {
+    ctor public JobInfo.TriggerContentUri(android.net.Uri, int);
+    method public int describeContents();
+    method public int getFlags();
+    method public android.net.Uri getUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.job.JobInfo.TriggerContentUri> CREATOR;
+    field public static final int FLAG_NOTIFY_FOR_DESCENDANTS = 1; // 0x1
+  }
+
   public class JobParameters implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.PersistableBundle getExtras();
     method public int getJobId();
+    method public java.lang.String[] getTriggeredContentAuthorities();
+    method public android.net.Uri[] getTriggeredContentUris();
     method public boolean isOverrideDeadlineExpired();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.job.JobParameters> CREATOR;
@@ -8019,6 +8041,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
+    field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
@@ -8373,7 +8396,6 @@
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
-    field public static final java.lang.String ACTION_AVAILABILITY_CHANGED = "android.intent.action.AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
     field public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
@@ -8457,6 +8479,7 @@
     field public static final java.lang.String ACTION_PROCESS_TEXT = "android.intent.action.PROCESS_TEXT";
     field public static final java.lang.String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED";
     field public static final java.lang.String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK";
+    field public static final java.lang.String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
     field public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT";
     field public static final java.lang.String ACTION_RUN = "android.intent.action.RUN";
     field public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
@@ -8550,6 +8573,7 @@
     field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
     field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
     field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+    field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
     field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
     field public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT";
@@ -9649,6 +9673,7 @@
     field public static final java.lang.String FEATURE_MIDI = "android.software.midi";
     field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
     field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
+    field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef";
     field public static final java.lang.String FEATURE_OPENGLES_EXTENSION_PACK = "android.hardware.opengles.aep";
     field public static final java.lang.String FEATURE_PICTURE_IN_PICTURE = "android.software.picture_in_picture";
     field public static final java.lang.String FEATURE_PRINTING = "android.software.print";
@@ -10093,7 +10118,6 @@
     method public java.lang.String getQuantityString(int, int, java.lang.Object...) throws android.content.res.Resources.NotFoundException;
     method public java.lang.String getQuantityString(int, int) throws android.content.res.Resources.NotFoundException;
     method public java.lang.CharSequence getQuantityText(int, int) throws android.content.res.Resources.NotFoundException;
-    method public java.util.Locale getResolvedLocale();
     method public java.lang.String getResourceEntryName(int) throws android.content.res.Resources.NotFoundException;
     method public java.lang.String getResourceName(int) throws android.content.res.Resources.NotFoundException;
     method public java.lang.String getResourcePackageName(int) throws android.content.res.Resources.NotFoundException;
@@ -13360,6 +13384,7 @@
     field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD = "android.sensor.magnetic_field";
     field public static final java.lang.String STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED = "android.sensor.magnetic_field_uncalibrated";
     field public static final deprecated java.lang.String STRING_TYPE_ORIENTATION = "android.sensor.orientation";
+    field public static final java.lang.String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof";
     field public static final java.lang.String STRING_TYPE_PRESSURE = "android.sensor.pressure";
     field public static final java.lang.String STRING_TYPE_PROXIMITY = "android.sensor.proximity";
     field public static final java.lang.String STRING_TYPE_RELATIVE_HUMIDITY = "android.sensor.relative_humidity";
@@ -13382,6 +13407,7 @@
     field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2
     field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe
     field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3
+    field public static final int TYPE_POSE_6DOF = 28; // 0x1c
     field public static final int TYPE_PRESSURE = 6; // 0x6
     field public static final int TYPE_PROXIMITY = 8; // 0x8
     field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
@@ -13583,6 +13609,7 @@
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AF;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AWB;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>> CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> DEPTH_DEPTH_IS_EXCLUSIVE;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> EDGE_AVAILABLE_EDGE_MODES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> FLASH_INFO_AVAILABLE;
@@ -13662,9 +13689,11 @@
     method public abstract void close();
     method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
     method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void createCaptureSessionByOutputConfiguration(java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
     method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void createReprocessableCaptureSessionWithConfigurations(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract java.lang.String getId();
     field public static final int TEMPLATE_MANUAL = 6; // 0x6
     field public static final int TEMPLATE_PREVIEW = 1; // 0x1
@@ -13821,6 +13850,7 @@
     field public static final int HOT_PIXEL_MODE_FAST = 1; // 0x1
     field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2
     field public static final int HOT_PIXEL_MODE_OFF = 0; // 0x0
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3; // 0x3
     field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1
     field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; // 0x2
     field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0
@@ -13942,6 +13972,7 @@
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_MODE;
+    field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_SCENE_MODE;
     field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
     field public static final android.os.Parcelable.Creator<android.hardware.camera2.CaptureRequest> CREATOR;
@@ -14020,6 +14051,7 @@
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_MODE;
+    field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_SCENE_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> EDGE_MODE;
@@ -14161,6 +14193,17 @@
     field public static final int METERING_WEIGHT_MIN = 0; // 0x0
   }
 
+  public final class OutputConfiguration implements android.os.Parcelable {
+    ctor public OutputConfiguration(android.view.Surface);
+    method public int describeContents();
+    method public android.view.Surface getSurface();
+    method public int getSurfaceSetId();
+    method public void setSurfaceSetId(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
+    field public static final int SURFACE_SET_ID_INVALID = -1; // 0xffffffff
+  }
+
   public final class RggbChannelVector {
     ctor public RggbChannelVector(float, float, float, float);
     method public void copyTo(float[], int);
@@ -20048,6 +20091,7 @@
     field public static final deprecated int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00
     field public static final deprecated int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
     field public static final java.lang.String FEATURE_AdaptivePlayback = "adaptive-playback";
+    field public static final java.lang.String FEATURE_IntraRefresh = "intra-refresh";
     field public static final java.lang.String FEATURE_SecurePlayback = "secure-playback";
     field public static final java.lang.String FEATURE_TunneledPlayback = "tunneled-playback";
     field public int[] colorFormats;
@@ -20090,6 +20134,21 @@
     field public static final int AVCProfileHigh422 = 32; // 0x20
     field public static final int AVCProfileHigh444 = 64; // 0x40
     field public static final int AVCProfileMain = 2; // 0x2
+    field public static final int DolbyVisionLevelFhd24 = 4; // 0x4
+    field public static final int DolbyVisionLevelFhd30 = 8; // 0x8
+    field public static final int DolbyVisionLevelFhd60 = 16; // 0x10
+    field public static final int DolbyVisionLevelHd24 = 1; // 0x1
+    field public static final int DolbyVisionLevelHd30 = 2; // 0x2
+    field public static final int DolbyVisionLevelUhd24 = 32; // 0x20
+    field public static final int DolbyVisionLevelUhd30 = 64; // 0x40
+    field public static final int DolbyVisionLevelUhd48 = 128; // 0x80
+    field public static final int DolbyVisionLevelUhd60 = 256; // 0x100
+    field public static final int DolbyVisionProfileDvavDen = 2; // 0x2
+    field public static final int DolbyVisionProfileDvavDer = 1; // 0x1
+    field public static final int DolbyVisionProfileDvheDen = 4; // 0x4
+    field public static final int DolbyVisionProfileDvheDer = 3; // 0x3
+    field public static final int DolbyVisionProfileDvheDtr = 5; // 0x5
+    field public static final int DolbyVisionProfileDvheStn = 6; // 0x6
     field public static final int H263Level10 = 1; // 0x1
     field public static final int H263Level20 = 2; // 0x2
     field public static final int H263Level30 = 4; // 0x4
@@ -20174,6 +20233,24 @@
     field public static final int VP8Level_Version2 = 4; // 0x4
     field public static final int VP8Level_Version3 = 8; // 0x8
     field public static final int VP8ProfileMain = 1; // 0x1
+    field public static final int VP9Level1 = 0; // 0x0
+    field public static final int VP9Level11 = 1; // 0x1
+    field public static final int VP9Level2 = 2; // 0x2
+    field public static final int VP9Level21 = 4; // 0x4
+    field public static final int VP9Level3 = 8; // 0x8
+    field public static final int VP9Level31 = 16; // 0x10
+    field public static final int VP9Level4 = 32; // 0x20
+    field public static final int VP9Level41 = 64; // 0x40
+    field public static final int VP9Level5 = 128; // 0x80
+    field public static final int VP9Level51 = 256; // 0x100
+    field public static final int VP9Level52 = 512; // 0x200
+    field public static final int VP9Level6 = 1024; // 0x400
+    field public static final int VP9Level61 = 2048; // 0x800
+    field public static final int VP9Level62 = 4096; // 0x1000
+    field public static final int VP9Profile0 = 0; // 0x0
+    field public static final int VP9Profile1 = 1; // 0x1
+    field public static final int VP9Profile2 = 2; // 0x2
+    field public static final int VP9Profile3 = 3; // 0x3
     field public int level;
     field public int profile;
   }
@@ -20421,6 +20498,7 @@
     field public static final java.lang.String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
     field public static final java.lang.String KEY_FRAME_RATE = "frame-rate";
     field public static final java.lang.String KEY_HEIGHT = "height";
+    field public static final java.lang.String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period";
     field public static final java.lang.String KEY_IS_ADTS = "is-adts";
     field public static final java.lang.String KEY_IS_AUTOSELECT = "is-autoselect";
     field public static final java.lang.String KEY_IS_DEFAULT = "is-default";
@@ -20742,9 +20820,11 @@
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
     method public android.view.Surface getSurface();
+    method public void pause() throws java.lang.IllegalStateException;
     method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
     method public void release();
     method public void reset();
+    method public void resume() throws java.lang.IllegalStateException;
     method public void setAudioChannels(int);
     method public void setAudioEncoder(int) throws java.lang.IllegalStateException;
     method public void setAudioEncodingBitRate(int);
@@ -20824,6 +20904,7 @@
     field public static final int DEFAULT = 0; // 0x0
     field public static final int H263 = 1; // 0x1
     field public static final int H264 = 2; // 0x2
+    field public static final int HEVC = 5; // 0x5
     field public static final int MPEG_4_SP = 3; // 0x3
     field public static final int VP8 = 4; // 0x4
   }
@@ -21712,7 +21793,11 @@
     method public android.media.session.MediaSession.Token getSessionToken();
     method public boolean isConnected();
     method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
+    method public void subscribe(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void unsubscribe(java.lang.String);
+    method public void unsubscribe(java.lang.String, android.os.Bundle);
+    field public static final java.lang.String EXTRA_PAGE = "android.media.browse.extra.PAGE";
+    field public static final java.lang.String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
   }
 
   public static class MediaBrowser.ConnectionCallback {
@@ -21745,7 +21830,9 @@
   public static abstract class MediaBrowser.SubscriptionCallback {
     ctor public MediaBrowser.SubscriptionCallback();
     method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
+    method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>, android.os.Bundle);
     method public void onError(java.lang.String);
+    method public void onError(java.lang.String, android.os.Bundle);
   }
 
 }
@@ -22183,6 +22270,7 @@
     method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
     method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
     method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+    method public static final android.net.Uri buildRecordedProgramUri(long);
     field public static final java.lang.String AUTHORITY = "android.media.tv";
   }
 
@@ -22319,13 +22407,49 @@
     field public static final java.lang.String TRAVEL = "TRAVEL";
   }
 
+  public static final class TvContract.RecordedPrograms implements android.media.tv.TvContract.BaseTvColumns {
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    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_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";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+    field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
+    field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
+    field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
+    field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_NUMBER = "season_number";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
+    field public static final android.net.Uri CONTENT_URI;
+  }
+
   public final class TvInputInfo implements android.os.Parcelable {
+    method public boolean canRecord();
     method public android.content.Intent createSettingsIntent();
     method public android.content.Intent createSetupIntent();
     method public int describeContents();
     method public java.lang.String getId();
     method public java.lang.String getParentId();
     method public android.content.pm.ServiceInfo getServiceInfo();
+    method public int getTunerCount();
     method public int getType();
     method public boolean isPassthroughInput();
     method public android.graphics.drawable.Drawable loadIcon(android.content.Context);
@@ -22345,6 +22469,13 @@
     field public static final int TYPE_VGA = 1005; // 0x3ed
   }
 
+  public static final class TvInputInfo.Builder {
+    ctor public TvInputInfo.Builder(android.content.Context, java.lang.Class<?>);
+    method public android.media.tv.TvInputInfo build() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public android.media.tv.TvInputInfo.Builder setCanRecord(boolean);
+    method public android.media.tv.TvInputInfo.Builder setTunerCount(int);
+  }
+
   public final class TvInputManager {
     method public int getInputState(java.lang.String);
     method public android.media.tv.TvInputInfo getTvInputInfo(java.lang.String);
@@ -22360,6 +22491,10 @@
     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_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
     field public static final int TIME_SHIFT_STATUS_UNAVAILABLE = 2; // 0x2
@@ -22377,12 +22512,15 @@
     method public void onInputAdded(java.lang.String);
     method public void onInputRemoved(java.lang.String);
     method public void onInputStateChanged(java.lang.String, int);
+    method public void onTvInputInfoChanged(java.lang.String, android.media.tv.TvInputInfo);
   }
 
   public abstract class TvInputService extends android.app.Service {
     ctor public TvInputService();
     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 final void setTvInputInfo(java.lang.String, 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";
   }
@@ -22395,6 +22533,18 @@
     method public final boolean onSetSurface(android.view.Surface);
   }
 
+  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 abstract void onStopRecording();
+  }
+
   public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
     ctor public TvInputService.Session(android.content.Context);
     method public void layoutSurface(int, int, int, int);
@@ -22422,6 +22572,7 @@
     method public long onTimeShiftGetCurrentPosition();
     method public long onTimeShiftGetStartPosition();
     method public void onTimeShiftPause();
+    method public void onTimeShiftPlay(android.net.Uri);
     method public void onTimeShiftResume();
     method public void onTimeShiftSeekTo(long);
     method public void onTimeShiftSetPlaybackParams(android.media.PlaybackParams);
@@ -22432,6 +22583,23 @@
     method public void setOverlayViewEnabled(boolean);
   }
 
+  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 stopRecording();
+  }
+
+  public class TvRecordingClient.RecordingCallback {
+    ctor public TvRecordingClient.RecordingCallback();
+    method public void onConnected();
+    method public void onDisconnected();
+    method public void onError(int);
+    method public void onRecordingStarted();
+    method public void onRecordingStopped(android.net.Uri);
+  }
+
   public final class TvTrackInfo implements android.os.Parcelable {
     method public int describeContents();
     method public final int getAudioChannelCount();
@@ -22483,6 +22651,7 @@
     method public void setStreamVolume(float);
     method public void setTimeShiftPositionCallback(android.media.tv.TvView.TimeShiftPositionCallback);
     method public void timeShiftPause();
+    method public void timeShiftPlay(java.lang.String, android.net.Uri);
     method public void timeShiftResume();
     method public void timeShiftSeekTo(long);
     method public void timeShiftSetPlaybackParams(android.media.PlaybackParams);
@@ -22558,6 +22727,7 @@
     field public static final int FORMAT_AUDIBLE = 47364; // 0xb904
     field public static final int FORMAT_AVI = 12298; // 0x300a
     field public static final int FORMAT_BMP = 14340; // 0x3804
+    field public static final int FORMAT_DEFINED = 14336; // 0x3800
     field public static final int FORMAT_DNG = 14353; // 0x3811
     field public static final int FORMAT_DPOF = 12294; // 0x3006
     field public static final int FORMAT_EXECUTABLE = 12291; // 0x3003
@@ -22663,6 +22833,7 @@
   }
 
   public class MtpDeviceInfo {
+    method public final int[] getEventsSupported();
     method public final java.lang.String getManufacturer();
     method public final java.lang.String getModel();
     method public final int[] getOperationsSupported();
@@ -22833,9 +23004,6 @@
     method public abstract void onNetworkActive();
   }
 
-  public static abstract class ConnectivityManager.RestrictBackgroundStatus implements java.lang.annotation.Annotation {
-  }
-
   public class Credentials {
     ctor public Credentials(int, int, int);
     method public int getGid();
@@ -23849,6 +24017,7 @@
     method public java.lang.String getAltSubjectMatch();
     method public java.lang.String getAnonymousIdentity();
     method public java.security.cert.X509Certificate getCaCertificate();
+    method public java.security.cert.X509Certificate[] getCaCertificates();
     method public java.security.cert.X509Certificate getClientCertificate();
     method public java.lang.String getDomainSuffixMatch();
     method public int getEapMethod();
@@ -23861,6 +24030,7 @@
     method public void setAltSubjectMatch(java.lang.String);
     method public void setAnonymousIdentity(java.lang.String);
     method public void setCaCertificate(java.security.cert.X509Certificate);
+    method public void setCaCertificates(java.security.cert.X509Certificate[]);
     method public void setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate);
     method public void setDomainSuffixMatch(java.lang.String);
     method public void setEapMethod(int);
@@ -24390,6 +24560,28 @@
     field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
   }
 
+  public abstract class HostNfcFService extends android.app.Service {
+    ctor public HostNfcFService();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract void onDeactivated(int);
+    method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle);
+    method public final void sendResponsePacket(byte[]);
+    field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
+    field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
+    field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service";
+  }
+
+  public final class NfcFCardEmulation {
+    method public boolean disableNfcFForegroundService(android.app.Activity);
+    method public boolean enableNfcFForegroundService(android.app.Activity, android.content.ComponentName);
+    method public static synchronized android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter);
+    method public java.lang.String getNfcid2ForService(android.content.ComponentName);
+    method public java.lang.String getSystemCodeForService(android.content.ComponentName);
+    method public boolean registerSystemCodeForService(android.content.ComponentName, java.lang.String);
+    method public boolean removeSystemCodeForService(android.content.ComponentName);
+    method public boolean setNfcid2ForService(android.content.ComponentName, java.lang.String);
+  }
+
   public abstract class OffHostApduService extends android.app.Service {
     ctor public OffHostApduService();
     method public abstract android.os.IBinder onBind(android.content.Intent);
@@ -27746,6 +27938,14 @@
     method public final synchronized android.os.CountDownTimer start();
   }
 
+  public final class CpuUsageInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getActive();
+    method public long getTotal();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.os.CpuUsageInfo> CREATOR;
+  }
+
   public class DeadObjectException extends android.os.RemoteException {
     ctor public DeadObjectException();
     ctor public DeadObjectException(java.lang.String);
@@ -27998,6 +28198,18 @@
     method public boolean quitSafely();
   }
 
+  public class HardwarePropertiesManager {
+    method public android.os.CpuUsageInfo[] getCpuUsages();
+    method public float[] getDeviceTemperatures(int);
+    method public float[] getFanSpeeds();
+    field public static final int DEVICE_TEMPERATURE_BATTERY = 2; // 0x2
+    field public static final int DEVICE_TEMPERATURE_CPU = 0; // 0x0
+    field public static final int DEVICE_TEMPERATURE_GPU = 1; // 0x1
+  }
+
+  public static abstract class HardwarePropertiesManager.DeviceTemperatureType implements java.lang.annotation.Annotation {
+  }
+
   public abstract interface IBinder {
     method public abstract void dump(java.io.FileDescriptor, java.lang.String[]) throws android.os.RemoteException;
     method public abstract void dumpAsync(java.io.FileDescriptor, java.lang.String[]) throws android.os.RemoteException;
@@ -28367,6 +28579,7 @@
     field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1
     field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
     field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
+    field public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 256; // 0x100
   }
 
   public final class PowerManager.WakeLock {
@@ -30725,10 +30938,14 @@
 
   public static final class ContactsContract.Intents {
     ctor public ContactsContract.Intents();
+    field public static final java.lang.String ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS = "android.provider.action.VOICE_SEND_MESSAGE_TO_CONTACTS";
     field public static final java.lang.String ATTACH_IMAGE = "com.android.contacts.action.ATTACH_IMAGE";
     field public static final java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
     field public static final java.lang.String EXTRA_CREATE_DESCRIPTION = "com.android.contacts.action.CREATE_DESCRIPTION";
     field public static final java.lang.String EXTRA_FORCE_CREATE = "com.android.contacts.action.FORCE_CREATE";
+    field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
+    field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_NAME = "android.provider.extra.RECIPIENT_CONTACT_NAME";
+    field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_URI = "android.provider.extra.RECIPIENT_CONTACT_URI";
     field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
     field public static final java.lang.String SEARCH_SUGGESTION_CLICKED = "android.provider.Contacts.SEARCH_SUGGESTION_CLICKED";
     field public static final java.lang.String SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED = "android.provider.Contacts.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED";
@@ -30974,6 +31191,7 @@
     method public static android.net.Uri buildRootsUri(java.lang.String);
     method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String);
     method public static android.net.Uri buildTreeDocumentUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri copyDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri);
     method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
@@ -30982,6 +31200,7 @@
     method public static java.lang.String getSearchDocumentsQuery(android.net.Uri);
     method public static java.lang.String getTreeDocumentId(android.net.Uri);
     method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
+    method public static android.net.Uri moveDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri, android.net.Uri);
     method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
     field public static final java.lang.String EXTRA_ERROR = "error";
     field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
@@ -32810,6 +33029,7 @@
     method public void getVarV(int, android.renderscript.FieldPacker);
     method protected void invoke(int);
     method protected void invoke(int, android.renderscript.FieldPacker);
+    method protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void setTimeZone(java.lang.String);
     method public void setVar(int, float);
     method public void setVar(int, double);
@@ -33661,9 +33881,11 @@
     method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public android.media.session.MediaSession.Token getSessionToken();
     method public void notifyChildrenChanged(java.lang.String);
+    method public void notifyChildrenChanged(java.lang.String, android.os.Bundle);
     method public android.os.IBinder onBind(android.content.Intent);
     method public abstract android.service.media.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
     method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
+    method public void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>, android.os.Bundle);
     method public void onLoadItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>);
     method public void setSessionToken(android.media.session.MediaSession.Token);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
@@ -33748,6 +33970,7 @@
     field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb
     field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
     field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
+    field public static final int REASON_PACKAGE_SUSPENDED = 15; // 0xf
     field public static final int REASON_TOPIC_BANNED = 14; // 0xe
     field public static final int REASON_USER_STOPPED = 6; // 0x6
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
@@ -34011,6 +34234,7 @@
     method public void setTheme(int);
     method public void show(android.os.Bundle, int);
     method public void startVoiceActivity(android.content.Intent);
+    field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10
     field public static final int SHOW_SOURCE_APPLICATION = 8; // 0x8
     field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4
     field public static final int SHOW_WITH_ASSIST = 1; // 0x1
@@ -34372,6 +34596,8 @@
 
   public abstract class UtteranceProgressListener {
     ctor public UtteranceProgressListener();
+    method public void onAudioAvailable(java.lang.String, byte[]);
+    method public void onBeginSynthesis(java.lang.String, int, int, int);
     method public abstract void onDone(java.lang.String);
     method public abstract deprecated void onError(java.lang.String);
     method public void onError(java.lang.String, int);
@@ -35119,6 +35345,7 @@
     method public static boolean hasProperty(int, int);
     method public boolean hasProperty(int);
     method public static java.lang.String propertiesToString(int);
+    field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
@@ -35259,6 +35486,7 @@
     method public final void setVideoProvider(android.telecom.Connection.VideoProvider);
     method public final void setVideoState(int);
     method public static java.lang.String stateToString(int);
+    field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
     field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
@@ -35638,6 +35866,7 @@
     field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
+    field public static final java.lang.String ACTION_SHOW_MISSED_CALLS_NOTIFICATION = "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
     field public static final java.lang.String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS";
     field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
     field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
@@ -35648,6 +35877,8 @@
     field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
     field public static final java.lang.String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
+    field public static final java.lang.String EXTRA_NOTIFICATION_COUNT = "android.telecom.extra.NOTIFICATION_COUNT";
+    field public static final java.lang.String EXTRA_NOTIFICATION_PHONE_NUMBER = "android.telecom.extra.NOTIFICATION_PHONE_NUMBER";
     field public static final java.lang.String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
     field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
     field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
@@ -35823,6 +36054,8 @@
 
   public final class CellIdentityGsm implements android.os.Parcelable {
     method public int describeContents();
+    method public int getArfcn();
+    method public int getBsic();
     method public int getCid();
     method public int getLac();
     method public int getMcc();
@@ -35835,6 +36068,7 @@
   public final class CellIdentityLte implements android.os.Parcelable {
     method public int describeContents();
     method public int getCi();
+    method public int getEarfcn();
     method public int getMcc();
     method public int getMnc();
     method public int getPci();
@@ -35850,6 +36084,7 @@
     method public int getMcc();
     method public int getMnc();
     method public int getPsc();
+    method public int getUarfcn();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityWcdma> CREATOR;
   }
@@ -36271,10 +36506,15 @@
     method public int getActiveSubscriptionInfoCountMax();
     method public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int);
     method public java.util.List<android.telephony.SubscriptionInfo> getActiveSubscriptionInfoList();
+    method public static int getDefaultDataSubscriptionId();
+    method public static int getDefaultSmsSubscriptionId();
+    method public static int getDefaultSubscriptionId();
+    method public static int getDefaultVoiceSubscriptionId();
     method public boolean isNetworkRoaming(int);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
     field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
     field public static final int DATA_ROAMING_ENABLE = 1; // 0x1
+    field public static final int INVALID_SUBSCRIPTION_ID = -1; // 0xffffffff
   }
 
   public static class SubscriptionManager.OnSubscriptionsChangedListener {
@@ -36286,32 +36526,49 @@
     method public boolean canChangeDtmfToneLength();
     method public java.util.List<android.telephony.CellInfo> getAllCellInfo();
     method public int getCallState();
+    method public int getCallState(int);
     method public android.telephony.CellLocation getCellLocation();
     method public int getDataActivity();
+    method public int getDataNetworkType(int);
     method public int getDataState();
     method public java.lang.String getDeviceId();
     method public java.lang.String getDeviceId(int);
     method public java.lang.String getDeviceSoftwareVersion();
     method public java.lang.String getGroupIdLevel1();
+    method public java.lang.String getGroupIdLevel1(int);
     method public java.lang.String getIccSimChallengeResponse(int, java.lang.String);
+    method public java.lang.String getLine1AlphaTag(int);
     method public java.lang.String getLine1Number();
+    method public java.lang.String getLine1Number(int);
     method public java.lang.String getMmsUAProfUrl();
     method public java.lang.String getMmsUserAgent();
     method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
     method public java.lang.String getNetworkCountryIso();
+    method public java.lang.String getNetworkCountryIso(int);
     method public java.lang.String getNetworkOperator();
+    method public java.lang.String getNetworkOperator(int);
     method public java.lang.String getNetworkOperatorName();
+    method public java.lang.String getNetworkOperatorName(int);
     method public int getNetworkType();
+    method public int getNetworkType(int);
     method public int getPhoneCount();
     method public int getPhoneType();
     method public java.lang.String getSimCountryIso();
+    method public java.lang.String getSimCountryIso(int);
     method public java.lang.String getSimOperator();
+    method public java.lang.String getSimOperator(int);
     method public java.lang.String getSimOperatorName();
+    method public java.lang.String getSimOperatorName(int);
     method public java.lang.String getSimSerialNumber();
+    method public java.lang.String getSimSerialNumber(int);
     method public int getSimState();
     method public java.lang.String getSubscriberId();
+    method public java.lang.String getSubscriberId(int);
     method public java.lang.String getVoiceMailAlphaTag();
+    method public java.lang.String getVoiceMailAlphaTag(int);
     method public java.lang.String getVoiceMailNumber();
+    method public java.lang.String getVoiceMailNumber(int);
+    method public int getVoiceNetworkType(int);
     method public android.net.Uri getVoicemailRingtoneUri(android.telecom.PhoneAccountHandle);
     method public boolean hasCarrierPrivileges();
     method public boolean hasIccCard();
@@ -36322,6 +36579,7 @@
     method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
     method public boolean isHearingAidCompatibilitySupported();
     method public boolean isNetworkRoaming();
+    method public boolean isNetworkRoaming(int);
     method public boolean isSmsCapable();
     method public boolean isTtyModeSupported();
     method public boolean isVoiceCapable();
@@ -36330,9 +36588,11 @@
     method public void listen(android.telephony.PhoneStateListener, int);
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
     method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
+    method public boolean setLine1NumberForDisplay(int, java.lang.String, java.lang.String);
     method public boolean setOperatorBrandOverride(java.lang.String);
     method public boolean setPreferredNetworkTypeToGlobal();
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
+    method public boolean setVoiceMailNumber(int, java.lang.String, java.lang.String);
     field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
     field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
     field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -37263,9 +37523,23 @@
 
   public class Html {
     method public static java.lang.String escapeHtml(java.lang.CharSequence);
-    method public static android.text.Spanned fromHtml(java.lang.String);
-    method public static android.text.Spanned fromHtml(java.lang.String, android.text.Html.ImageGetter, android.text.Html.TagHandler);
-    method public static java.lang.String toHtml(android.text.Spanned);
+    method public static deprecated android.text.Spanned fromHtml(java.lang.String);
+    method public static android.text.Spanned fromHtml(java.lang.String, int);
+    method public static deprecated android.text.Spanned fromHtml(java.lang.String, android.text.Html.ImageGetter, android.text.Html.TagHandler);
+    method public static android.text.Spanned fromHtml(java.lang.String, int, android.text.Html.ImageGetter, android.text.Html.TagHandler);
+    method public static deprecated java.lang.String toHtml(android.text.Spanned);
+    method public static java.lang.String toHtml(android.text.Spanned, int);
+    field public static final int FROM_HTML_MODE_COMPACT = 63; // 0x3f
+    field public static final int FROM_HTML_MODE_LEGACY = 0; // 0x0
+    field public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256; // 0x100
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32; // 0x20
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16; // 0x10
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2; // 0x2
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8; // 0x8
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4; // 0x4
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1; // 0x1
+    field public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0; // 0x0
+    field public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1; // 0x1
   }
 
   public static abstract interface Html.ImageGetter {
@@ -48116,7 +48390,6 @@
     method public boolean setReadable(boolean);
     method public boolean setWritable(boolean, boolean);
     method public boolean setWritable(boolean);
-    method public java.nio.file.Path toPath();
     method public java.net.URI toURI();
     method public deprecated java.net.URL toURL() throws java.net.MalformedURLException;
     field public static final java.lang.String pathSeparator;
@@ -49669,6 +49942,9 @@
     field public static final java.lang.Class<java.lang.Float> TYPE;
   }
 
+  public abstract class FunctionalInterface implements java.lang.annotation.Annotation {
+  }
+
   public class IllegalAccessError extends java.lang.IncompatibleClassChangeError {
     ctor public IllegalAccessError();
     ctor public IllegalAccessError(java.lang.String);
@@ -50798,6 +51074,7 @@
     method public java.lang.Object invoke(java.lang.Object, java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
     method public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>);
     method public boolean isBridge();
+    method public boolean isDefault();
     method public boolean isSynthetic();
     method public boolean isVarArgs();
     method public java.lang.String toGenericString();
@@ -52211,25 +52488,6 @@
     ctor public AsynchronousCloseException();
   }
 
-  public abstract class AsynchronousFileChannel implements java.nio.channels.AsynchronousChannel {
-    ctor protected AsynchronousFileChannel();
-    method public abstract void force(boolean) throws java.io.IOException;
-    method public abstract void lock(long, long, boolean, A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock, ? super A>);
-    method public final void lock(A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock, ? super A>);
-    method public abstract java.util.concurrent.Future<java.nio.channels.FileLock> lock(long, long, boolean);
-    method public final java.util.concurrent.Future<java.nio.channels.FileLock> lock();
-    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public abstract void read(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer, long);
-    method public abstract long size() throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousFileChannel truncate(long) throws java.io.IOException;
-    method public abstract java.nio.channels.FileLock tryLock(long, long, boolean) throws java.io.IOException;
-    method public final java.nio.channels.FileLock tryLock() throws java.io.IOException;
-    method public abstract void write(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer, long);
-  }
-
   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>);
@@ -52338,8 +52596,6 @@
     method public abstract java.nio.channels.FileLock lock(long, long, boolean) throws java.io.IOException;
     method public final java.nio.channels.FileLock lock() throws java.io.IOException;
     method public abstract java.nio.MappedByteBuffer map(java.nio.channels.FileChannel.MapMode, long, long) throws java.io.IOException;
-    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
     method public abstract long position() throws java.io.IOException;
     method public abstract java.nio.channels.FileChannel position(long) throws java.io.IOException;
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
@@ -52366,7 +52622,6 @@
 
   public abstract class FileLock implements java.lang.AutoCloseable {
     ctor protected FileLock(java.nio.channels.FileChannel, long, long, boolean);
-    ctor protected FileLock(java.nio.channels.AsynchronousFileChannel, long, long, boolean);
     method public java.nio.channels.Channel acquiredBy();
     method public final java.nio.channels.FileChannel channel();
     method public final void close() throws java.io.IOException;
@@ -52816,592 +53071,6 @@
 
 }
 
-package java.nio.file {
-
-  public class AccessDeniedException extends java.nio.file.FileSystemException {
-    ctor public AccessDeniedException(java.lang.String);
-    ctor public AccessDeniedException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public final class AccessMode extends java.lang.Enum {
-    method public static java.nio.file.AccessMode valueOf(java.lang.String);
-    method public static final java.nio.file.AccessMode[] values();
-    enum_constant public static final java.nio.file.AccessMode EXECUTE;
-    enum_constant public static final java.nio.file.AccessMode READ;
-    enum_constant public static final java.nio.file.AccessMode WRITE;
-  }
-
-  public class AtomicMoveNotSupportedException extends java.nio.file.FileSystemException {
-    ctor public AtomicMoveNotSupportedException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public class ClosedDirectoryStreamException extends java.lang.IllegalStateException {
-    ctor public ClosedDirectoryStreamException();
-  }
-
-  public class ClosedFileSystemException extends java.lang.IllegalStateException {
-    ctor public ClosedFileSystemException();
-  }
-
-  public class ClosedWatchServiceException extends java.lang.IllegalStateException {
-    ctor public ClosedWatchServiceException();
-  }
-
-  public abstract interface CopyOption {
-  }
-
-  public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
-    ctor public DirectoryIteratorException(java.io.IOException);
-  }
-
-  public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
-    ctor public DirectoryNotEmptyException(java.lang.String);
-  }
-
-  public abstract interface DirectoryStream implements java.io.Closeable java.lang.Iterable {
-    method public abstract java.util.Iterator<T> iterator();
-  }
-
-  public static abstract interface DirectoryStream.Filter {
-    method public abstract boolean accept(T) throws java.io.IOException;
-  }
-
-  public class FileAlreadyExistsException extends java.nio.file.FileSystemException {
-    ctor public FileAlreadyExistsException(java.lang.String);
-    ctor public FileAlreadyExistsException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public abstract class FileStore {
-    ctor protected FileStore();
-    method public abstract java.lang.Object getAttribute(java.lang.String) throws java.io.IOException;
-    method public abstract V getFileStoreAttributeView(java.lang.Class<V>);
-    method public abstract long getTotalSpace() throws java.io.IOException;
-    method public abstract long getUnallocatedSpace() throws java.io.IOException;
-    method public abstract long getUsableSpace() throws java.io.IOException;
-    method public abstract boolean isReadOnly();
-    method public abstract java.lang.String name();
-    method public abstract boolean supportsFileAttributeView(java.lang.Class<? extends java.nio.file.attribute.FileAttributeView>);
-    method public abstract boolean supportsFileAttributeView(java.lang.String);
-    method public abstract java.lang.String type();
-  }
-
-  public abstract class FileSystem implements java.io.Closeable {
-    ctor protected FileSystem();
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.lang.Iterable<java.nio.file.FileStore> getFileStores();
-    method public abstract java.nio.file.Path getPath(java.lang.String, java.lang.String...);
-    method public abstract java.nio.file.PathMatcher getPathMatcher(java.lang.String);
-    method public abstract java.lang.Iterable<java.nio.file.Path> getRootDirectories();
-    method public abstract java.lang.String getSeparator();
-    method public abstract java.nio.file.attribute.UserPrincipalLookupService getUserPrincipalLookupService();
-    method public abstract boolean isOpen();
-    method public abstract boolean isReadOnly();
-    method public abstract java.nio.file.WatchService newWatchService() throws java.io.IOException;
-    method public abstract java.nio.file.spi.FileSystemProvider provider();
-    method public abstract java.util.Set<java.lang.String> supportedFileAttributeViews();
-  }
-
-  public class FileSystemAlreadyExistsException extends java.lang.RuntimeException {
-    ctor public FileSystemAlreadyExistsException();
-    ctor public FileSystemAlreadyExistsException(java.lang.String);
-  }
-
-  public class FileSystemException extends java.io.IOException {
-    ctor public FileSystemException(java.lang.String);
-    ctor public FileSystemException(java.lang.String, java.lang.String, java.lang.String);
-    method public java.lang.String getFile();
-    method public java.lang.String getOtherFile();
-    method public java.lang.String getReason();
-  }
-
-  public class FileSystemLoopException extends java.nio.file.FileSystemException {
-    ctor public FileSystemLoopException(java.lang.String);
-  }
-
-  public class FileSystemNotFoundException extends java.lang.RuntimeException {
-    ctor public FileSystemNotFoundException();
-    ctor public FileSystemNotFoundException(java.lang.String);
-  }
-
-  public final class FileSystems {
-    method public static java.nio.file.FileSystem getDefault();
-    method public static java.nio.file.FileSystem getFileSystem(java.net.URI);
-    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>) throws java.io.IOException;
-    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>, java.lang.ClassLoader) throws java.io.IOException;
-    method public static java.nio.file.FileSystem newFileSystem(java.nio.file.Path, java.lang.ClassLoader) throws java.io.IOException;
-  }
-
-  public final class FileVisitOption extends java.lang.Enum {
-    method public static java.nio.file.FileVisitOption valueOf(java.lang.String);
-    method public static final java.nio.file.FileVisitOption[] values();
-    enum_constant public static final java.nio.file.FileVisitOption FOLLOW_LINKS;
-  }
-
-  public final class FileVisitResult extends java.lang.Enum {
-    method public static java.nio.file.FileVisitResult valueOf(java.lang.String);
-    method public static final java.nio.file.FileVisitResult[] values();
-    enum_constant public static final java.nio.file.FileVisitResult CONTINUE;
-    enum_constant public static final java.nio.file.FileVisitResult SKIP_SIBLINGS;
-    enum_constant public static final java.nio.file.FileVisitResult SKIP_SUBTREE;
-    enum_constant public static final java.nio.file.FileVisitResult TERMINATE;
-  }
-
-  public abstract interface FileVisitor {
-    method public abstract java.nio.file.FileVisitResult postVisitDirectory(T, java.io.IOException) throws java.io.IOException;
-    method public abstract java.nio.file.FileVisitResult preVisitDirectory(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public abstract java.nio.file.FileVisitResult visitFile(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
-    method public abstract java.nio.file.FileVisitResult visitFileFailed(T, java.io.IOException) throws java.io.IOException;
-  }
-
-  public final class Files {
-    method public static java.nio.file.Path copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static long copy(java.io.InputStream, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static long copy(java.nio.file.Path, java.io.OutputStream) throws java.io.IOException;
-    method public static java.nio.file.Path createDirectories(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createFile(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempDirectory(java.nio.file.Path, java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempDirectory(java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempFile(java.nio.file.Path, java.lang.String, java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.file.Path createTempFile(java.lang.String, java.lang.String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static void delete(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean exists(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static java.lang.Object getAttribute(java.nio.file.Path, java.lang.String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static V getFileAttributeView(java.nio.file.Path, java.lang.Class<V>, java.nio.file.LinkOption...);
-    method public static java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.attribute.FileTime getLastModifiedTime(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.attribute.UserPrincipal getOwner(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> getPosixFilePermissions(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static boolean isDirectory(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static boolean isExecutable(java.nio.file.Path);
-    method public static boolean isHidden(java.nio.file.Path) throws java.io.IOException;
-    method public static boolean isReadable(java.nio.file.Path);
-    method public static boolean isRegularFile(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public static boolean isSymbolicLink(java.nio.file.Path);
-    method public static boolean isWritable(java.nio.file.Path);
-    method public static java.nio.file.Path move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public static java.io.BufferedReader newBufferedReader(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
-    method public static java.io.BufferedWriter newBufferedWriter(java.nio.file.Path, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.lang.String) throws java.io.IOException;
-    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static boolean notExists(java.nio.file.Path, java.nio.file.LinkOption...);
-    method public static java.lang.String probeContentType(java.nio.file.Path) throws java.io.IOException;
-    method public static byte[] readAllBytes(java.nio.file.Path) throws java.io.IOException;
-    method public static java.util.List<java.lang.String> readAllLines(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
-    method public static A readAttributes(java.nio.file.Path, java.lang.Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.util.Map<java.lang.String, java.lang.Object> readAttributes(java.nio.file.Path, java.lang.String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path setAttribute(java.nio.file.Path, java.lang.String, java.lang.Object, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public static java.nio.file.Path setLastModifiedTime(java.nio.file.Path, java.nio.file.attribute.FileTime) throws java.io.IOException;
-    method public static java.nio.file.Path setOwner(java.nio.file.Path, java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
-    method public static java.nio.file.Path setPosixFilePermissions(java.nio.file.Path, java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
-    method public static long size(java.nio.file.Path) throws java.io.IOException;
-    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.util.Set<java.nio.file.FileVisitOption>, int, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
-    method public static java.nio.file.Path write(java.nio.file.Path, byte[], java.nio.file.OpenOption...) throws java.io.IOException;
-    method public static java.nio.file.Path write(java.nio.file.Path, java.lang.Iterable<? extends java.lang.CharSequence>, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
-  }
-
-  public class InvalidPathException extends java.lang.IllegalArgumentException {
-    ctor public InvalidPathException(java.lang.String, java.lang.String, int);
-    ctor public InvalidPathException(java.lang.String, java.lang.String);
-    method public int getIndex();
-    method public java.lang.String getInput();
-    method public java.lang.String getReason();
-  }
-
-  public final class LinkOption extends java.lang.Enum implements java.nio.file.CopyOption java.nio.file.OpenOption {
-    method public static java.nio.file.LinkOption valueOf(java.lang.String);
-    method public static final java.nio.file.LinkOption[] values();
-    enum_constant public static final java.nio.file.LinkOption NOFOLLOW_LINKS;
-  }
-
-  public final class LinkPermission extends java.security.BasicPermission {
-    ctor public LinkPermission(java.lang.String);
-    ctor public LinkPermission(java.lang.String, java.lang.String);
-  }
-
-  public class NoSuchFileException extends java.nio.file.FileSystemException {
-    ctor public NoSuchFileException(java.lang.String);
-    ctor public NoSuchFileException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public class NotDirectoryException extends java.nio.file.FileSystemException {
-    ctor public NotDirectoryException(java.lang.String);
-  }
-
-  public class NotLinkException extends java.nio.file.FileSystemException {
-    ctor public NotLinkException(java.lang.String);
-    ctor public NotLinkException(java.lang.String, java.lang.String, java.lang.String);
-  }
-
-  public abstract interface OpenOption {
-  }
-
-  public abstract interface Path implements java.lang.Comparable java.lang.Iterable java.nio.file.Watchable {
-    method public abstract int compareTo(java.nio.file.Path);
-    method public abstract boolean endsWith(java.nio.file.Path);
-    method public abstract boolean endsWith(java.lang.String);
-    method public abstract boolean equals(java.lang.Object);
-    method public abstract java.nio.file.Path getFileName();
-    method public abstract java.nio.file.FileSystem getFileSystem();
-    method public abstract java.nio.file.Path getName(int);
-    method public abstract int getNameCount();
-    method public abstract java.nio.file.Path getParent();
-    method public abstract java.nio.file.Path getRoot();
-    method public abstract int hashCode();
-    method public abstract boolean isAbsolute();
-    method public abstract java.util.Iterator<java.nio.file.Path> iterator();
-    method public abstract java.nio.file.Path normalize();
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>[], java.nio.file.WatchEvent.Modifier...) throws java.io.IOException;
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.Path relativize(java.nio.file.Path);
-    method public abstract java.nio.file.Path resolve(java.nio.file.Path);
-    method public abstract java.nio.file.Path resolve(java.lang.String);
-    method public abstract java.nio.file.Path resolveSibling(java.nio.file.Path);
-    method public abstract java.nio.file.Path resolveSibling(java.lang.String);
-    method public abstract boolean startsWith(java.nio.file.Path);
-    method public abstract boolean startsWith(java.lang.String);
-    method public abstract java.nio.file.Path subpath(int, int);
-    method public abstract java.nio.file.Path toAbsolutePath();
-    method public abstract java.io.File toFile();
-    method public abstract java.nio.file.Path toRealPath(java.nio.file.LinkOption...) throws java.io.IOException;
-    method public abstract java.lang.String toString();
-    method public abstract java.net.URI toUri();
-  }
-
-  public abstract interface PathMatcher {
-    method public abstract boolean matches(java.nio.file.Path);
-  }
-
-  public final class Paths {
-    method public static java.nio.file.Path get(java.lang.String, java.lang.String...);
-    method public static java.nio.file.Path get(java.net.URI);
-  }
-
-  public class ProviderMismatchException extends java.lang.IllegalArgumentException {
-    ctor public ProviderMismatchException();
-    ctor public ProviderMismatchException(java.lang.String);
-  }
-
-  public class ProviderNotFoundException extends java.lang.RuntimeException {
-    ctor public ProviderNotFoundException();
-    ctor public ProviderNotFoundException(java.lang.String);
-  }
-
-  public class ReadOnlyFileSystemException extends java.lang.UnsupportedOperationException {
-    ctor public ReadOnlyFileSystemException();
-  }
-
-  public abstract interface SecureDirectoryStream implements java.nio.file.DirectoryStream {
-    method public abstract void deleteDirectory(T) throws java.io.IOException;
-    method public abstract void deleteFile(T) throws java.io.IOException;
-    method public abstract V getFileAttributeView(java.lang.Class<V>);
-    method public abstract V getFileAttributeView(T, java.lang.Class<V>, java.nio.file.LinkOption...);
-    method public abstract void move(T, java.nio.file.SecureDirectoryStream<T>, T) throws java.io.IOException;
-    method public abstract java.nio.channels.SeekableByteChannel newByteChannel(T, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.SecureDirectoryStream<T> newDirectoryStream(T, java.nio.file.LinkOption...) throws java.io.IOException;
-  }
-
-  public final class StandardCopyOption extends java.lang.Enum implements java.nio.file.CopyOption {
-    method public static java.nio.file.StandardCopyOption valueOf(java.lang.String);
-    method public static final java.nio.file.StandardCopyOption[] values();
-    enum_constant public static final java.nio.file.StandardCopyOption ATOMIC_MOVE;
-    enum_constant public static final java.nio.file.StandardCopyOption COPY_ATTRIBUTES;
-    enum_constant public static final java.nio.file.StandardCopyOption REPLACE_EXISTING;
-  }
-
-  public final class StandardOpenOption extends java.lang.Enum implements java.nio.file.OpenOption {
-    method public static java.nio.file.StandardOpenOption valueOf(java.lang.String);
-    method public static final java.nio.file.StandardOpenOption[] values();
-    enum_constant public static final java.nio.file.StandardOpenOption APPEND;
-    enum_constant public static final java.nio.file.StandardOpenOption CREATE;
-    enum_constant public static final java.nio.file.StandardOpenOption CREATE_NEW;
-    enum_constant public static final java.nio.file.StandardOpenOption DELETE_ON_CLOSE;
-    enum_constant public static final java.nio.file.StandardOpenOption DSYNC;
-    enum_constant public static final java.nio.file.StandardOpenOption READ;
-    enum_constant public static final java.nio.file.StandardOpenOption SPARSE;
-    enum_constant public static final java.nio.file.StandardOpenOption SYNC;
-    enum_constant public static final java.nio.file.StandardOpenOption TRUNCATE_EXISTING;
-    enum_constant public static final java.nio.file.StandardOpenOption WRITE;
-  }
-
-  public final class StandardWatchEventKinds {
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_CREATE;
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_DELETE;
-    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_MODIFY;
-    field public static final java.nio.file.WatchEvent.Kind<java.lang.Object> OVERFLOW;
-  }
-
-  public abstract interface WatchEvent {
-    method public abstract T context();
-    method public abstract int count();
-    method public abstract java.nio.file.WatchEvent.Kind<T> kind();
-  }
-
-  public static abstract interface WatchEvent.Kind {
-    method public abstract java.lang.String name();
-    method public abstract java.lang.Class<T> type();
-  }
-
-  public static abstract interface WatchEvent.Modifier {
-    method public abstract java.lang.String name();
-  }
-
-  public abstract interface WatchKey {
-    method public abstract void cancel();
-    method public abstract boolean isValid();
-    method public abstract java.util.List<java.nio.file.WatchEvent<?>> pollEvents();
-    method public abstract boolean reset();
-    method public abstract java.nio.file.Watchable watchable();
-  }
-
-  public abstract interface WatchService implements java.io.Closeable {
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.nio.file.WatchKey poll();
-    method public abstract java.nio.file.WatchKey poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public abstract java.nio.file.WatchKey take() throws java.lang.InterruptedException;
-  }
-
-  public abstract interface Watchable {
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>[], java.nio.file.WatchEvent.Modifier...) throws java.io.IOException;
-    method public abstract java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>...) throws java.io.IOException;
-  }
-
-}
-
-package java.nio.file.attribute {
-
-  public final class AclEntry {
-    method public java.util.Set<java.nio.file.attribute.AclEntryFlag> flags();
-    method public static java.nio.file.attribute.AclEntry.Builder newBuilder();
-    method public static java.nio.file.attribute.AclEntry.Builder newBuilder(java.nio.file.attribute.AclEntry);
-    method public java.util.Set<java.nio.file.attribute.AclEntryPermission> permissions();
-    method public java.nio.file.attribute.UserPrincipal principal();
-    method public java.nio.file.attribute.AclEntryType type();
-  }
-
-  public static final class AclEntry.Builder {
-    method public java.nio.file.attribute.AclEntry build();
-    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.util.Set<java.nio.file.attribute.AclEntryFlag>);
-    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.nio.file.attribute.AclEntryFlag...);
-    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.util.Set<java.nio.file.attribute.AclEntryPermission>);
-    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.nio.file.attribute.AclEntryPermission...);
-    method public java.nio.file.attribute.AclEntry.Builder setPrincipal(java.nio.file.attribute.UserPrincipal);
-    method public java.nio.file.attribute.AclEntry.Builder setType(java.nio.file.attribute.AclEntryType);
-  }
-
-  public final class AclEntryFlag extends java.lang.Enum {
-    method public static java.nio.file.attribute.AclEntryFlag valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.AclEntryFlag[] values();
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag DIRECTORY_INHERIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag FILE_INHERIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag INHERIT_ONLY;
-    enum_constant public static final java.nio.file.attribute.AclEntryFlag NO_PROPAGATE_INHERIT;
-  }
-
-  public final class AclEntryPermission extends java.lang.Enum {
-    method public static java.nio.file.attribute.AclEntryPermission valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.AclEntryPermission[] values();
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission APPEND_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE_CHILD;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission EXECUTE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ACL;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ATTRIBUTES;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_NAMED_ATTRS;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission SYNCHRONIZE;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ACL;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ATTRIBUTES;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_DATA;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_NAMED_ATTRS;
-    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_OWNER;
-    field public static final java.nio.file.attribute.AclEntryPermission ADD_FILE;
-    field public static final java.nio.file.attribute.AclEntryPermission ADD_SUBDIRECTORY;
-    field public static final java.nio.file.attribute.AclEntryPermission LIST_DIRECTORY;
-  }
-
-  public final class AclEntryType extends java.lang.Enum {
-    method public static java.nio.file.attribute.AclEntryType valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.AclEntryType[] values();
-    enum_constant public static final java.nio.file.attribute.AclEntryType ALARM;
-    enum_constant public static final java.nio.file.attribute.AclEntryType ALLOW;
-    enum_constant public static final java.nio.file.attribute.AclEntryType AUDIT;
-    enum_constant public static final java.nio.file.attribute.AclEntryType DENY;
-  }
-
-  public abstract interface AclFileAttributeView implements java.nio.file.attribute.FileOwnerAttributeView {
-    method public abstract java.util.List<java.nio.file.attribute.AclEntry> getAcl() throws java.io.IOException;
-    method public abstract java.lang.String name();
-    method public abstract void setAcl(java.util.List<java.nio.file.attribute.AclEntry>) throws java.io.IOException;
-  }
-
-  public abstract interface AttributeView {
-    method public abstract java.lang.String name();
-  }
-
-  public abstract interface BasicFileAttributeView implements java.nio.file.attribute.FileAttributeView {
-    method public abstract java.lang.String name();
-    method public abstract java.nio.file.attribute.BasicFileAttributes readAttributes() throws java.io.IOException;
-    method public abstract void setTimes(java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime) throws java.io.IOException;
-  }
-
-  public abstract interface BasicFileAttributes {
-    method public abstract java.nio.file.attribute.FileTime creationTime();
-    method public abstract java.lang.Object fileKey();
-    method public abstract boolean isDirectory();
-    method public abstract boolean isOther();
-    method public abstract boolean isRegularFile();
-    method public abstract boolean isSymbolicLink();
-    method public abstract java.nio.file.attribute.FileTime lastAccessTime();
-    method public abstract java.nio.file.attribute.FileTime lastModifiedTime();
-    method public abstract long size();
-  }
-
-  public abstract interface DosFileAttributeView implements java.nio.file.attribute.BasicFileAttributeView {
-    method public abstract java.lang.String name();
-    method public abstract java.nio.file.attribute.DosFileAttributes readAttributes() throws java.io.IOException;
-    method public abstract void setArchive(boolean) throws java.io.IOException;
-    method public abstract void setHidden(boolean) throws java.io.IOException;
-    method public abstract void setReadOnly(boolean) throws java.io.IOException;
-    method public abstract void setSystem(boolean) throws java.io.IOException;
-  }
-
-  public abstract interface DosFileAttributes implements java.nio.file.attribute.BasicFileAttributes {
-    method public abstract boolean isArchive();
-    method public abstract boolean isHidden();
-    method public abstract boolean isReadOnly();
-    method public abstract boolean isSystem();
-  }
-
-  public abstract interface FileAttribute {
-    method public abstract java.lang.String name();
-    method public abstract T value();
-  }
-
-  public abstract interface FileAttributeView implements java.nio.file.attribute.AttributeView {
-  }
-
-  public abstract interface FileOwnerAttributeView implements java.nio.file.attribute.FileAttributeView {
-    method public abstract java.nio.file.attribute.UserPrincipal getOwner() throws java.io.IOException;
-    method public abstract java.lang.String name();
-    method public abstract void setOwner(java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
-  }
-
-  public abstract interface FileStoreAttributeView implements java.nio.file.attribute.AttributeView {
-  }
-
-  public final class FileTime implements java.lang.Comparable {
-    method public int compareTo(java.nio.file.attribute.FileTime);
-    method public static java.nio.file.attribute.FileTime from(long, java.util.concurrent.TimeUnit);
-    method public static java.nio.file.attribute.FileTime fromMillis(long);
-    method public long to(java.util.concurrent.TimeUnit);
-    method public long toMillis();
-  }
-
-  public abstract interface GroupPrincipal implements java.nio.file.attribute.UserPrincipal {
-  }
-
-  public abstract interface PosixFileAttributeView implements java.nio.file.attribute.BasicFileAttributeView java.nio.file.attribute.FileOwnerAttributeView {
-    method public abstract java.lang.String name();
-    method public abstract java.nio.file.attribute.PosixFileAttributes readAttributes() throws java.io.IOException;
-    method public abstract void setGroup(java.nio.file.attribute.GroupPrincipal) throws java.io.IOException;
-    method public abstract void setPermissions(java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
-  }
-
-  public abstract interface PosixFileAttributes implements java.nio.file.attribute.BasicFileAttributes {
-    method public abstract java.nio.file.attribute.GroupPrincipal group();
-    method public abstract java.nio.file.attribute.UserPrincipal owner();
-    method public abstract java.util.Set<java.nio.file.attribute.PosixFilePermission> permissions();
-  }
-
-  public final class PosixFilePermission extends java.lang.Enum {
-    method public static java.nio.file.attribute.PosixFilePermission valueOf(java.lang.String);
-    method public static final java.nio.file.attribute.PosixFilePermission[] values();
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_WRITE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_WRITE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_EXECUTE;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_READ;
-    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_WRITE;
-  }
-
-  public final class PosixFilePermissions {
-    method public static java.nio.file.attribute.FileAttribute<java.util.Set<java.nio.file.attribute.PosixFilePermission>> asFileAttribute(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
-    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> fromString(java.lang.String);
-    method public static java.lang.String toString(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
-  }
-
-  public abstract interface UserPrincipal implements java.security.Principal {
-  }
-
-  public abstract class UserPrincipalLookupService {
-    ctor protected UserPrincipalLookupService();
-    method public abstract java.nio.file.attribute.GroupPrincipal lookupPrincipalByGroupName(java.lang.String) throws java.io.IOException;
-    method public abstract java.nio.file.attribute.UserPrincipal lookupPrincipalByName(java.lang.String) throws java.io.IOException;
-  }
-
-  public class UserPrincipalNotFoundException extends java.io.IOException {
-    ctor public UserPrincipalNotFoundException(java.lang.String);
-    method public java.lang.String getName();
-  }
-
-}
-
-package java.nio.file.spi {
-
-  public abstract class FileSystemProvider {
-    ctor protected FileSystemProvider();
-    method public abstract void checkAccess(java.nio.file.Path, java.nio.file.AccessMode...) throws java.io.IOException;
-    method public abstract void copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public abstract void createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public void createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public void createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract void delete(java.nio.file.Path) throws java.io.IOException;
-    method public boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
-    method public abstract V getFileAttributeView(java.nio.file.Path, java.lang.Class<V>, java.nio.file.LinkOption...);
-    method public abstract java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
-    method public abstract java.nio.file.FileSystem getFileSystem(java.net.URI);
-    method public abstract java.nio.file.Path getPath(java.net.URI);
-    method public abstract java.lang.String getScheme();
-    method public static java.util.List<java.nio.file.spi.FileSystemProvider> installedProviders();
-    method public abstract boolean isHidden(java.nio.file.Path) throws java.io.IOException;
-    method public abstract boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
-    method public abstract void move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
-    method public java.nio.channels.AsynchronousFileChannel newAsynchronousFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
-    method public java.nio.channels.FileChannel newFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
-    method public abstract java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String, ?>) throws java.io.IOException;
-    method public java.nio.file.FileSystem newFileSystem(java.nio.file.Path, java.util.Map<java.lang.String, ?>) throws java.io.IOException;
-    method public java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
-    method public abstract A readAttributes(java.nio.file.Path, java.lang.Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public abstract java.util.Map<java.lang.String, java.lang.Object> readAttributes(java.nio.file.Path, java.lang.String, java.nio.file.LinkOption...) throws java.io.IOException;
-    method public java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
-    method public abstract void setAttribute(java.nio.file.Path, java.lang.String, java.lang.Object, java.nio.file.LinkOption...) throws java.io.IOException;
-  }
-
-  public abstract class FileTypeDetector {
-    ctor protected FileTypeDetector();
-    method public abstract java.lang.String probeContentType(java.nio.file.Path) throws java.io.IOException;
-  }
-
-}
-
 package java.security {
 
   public final class AccessControlContext {
@@ -57998,8 +57667,6 @@
     ctor public Scanner(java.io.InputStream, java.lang.String);
     ctor public Scanner(java.io.File) throws java.io.FileNotFoundException;
     ctor public Scanner(java.io.File, java.lang.String) throws java.io.FileNotFoundException;
-    ctor public Scanner(java.nio.file.Path) throws java.io.IOException;
-    ctor public Scanner(java.nio.file.Path, java.lang.String) throws java.io.IOException;
     ctor public Scanner(java.lang.String);
     ctor public Scanner(java.nio.channels.ReadableByteChannel);
     ctor public Scanner(java.nio.channels.ReadableByteChannel, java.lang.String);
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
index 6dc3cd1..b83484d 100644
--- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -18,6 +18,7 @@
 
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
+import android.app.admin.DevicePolicyManager;
 import android.app.admin.IDevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -143,6 +144,10 @@
             mDevicePolicyManager.removeActiveAdmin(mComponent, UserHandle.USER_SYSTEM);
             throw e;
         }
+
+        mDevicePolicyManager.setUserProvisioningState(
+                DevicePolicyManager.STATE_USER_SETUP_FINALIZED, mUserId);
+
         System.out.println("Success: Device owner set to package " + mComponent);
         System.out.println("Active admin set to component " + mComponent.toShortString());
     }
@@ -161,6 +166,10 @@
             mDevicePolicyManager.removeActiveAdmin(mComponent, mUserId);
             throw e;
         }
+
+        mDevicePolicyManager.setUserProvisioningState(
+                DevicePolicyManager.STATE_USER_SETUP_FINALIZED, mUserId);
+
         System.out.println("Success: Active admin and profile owner set to "
                 + mComponent.toShortString() + " for user " + mUserId);
     }
@@ -180,4 +189,4 @@
             throw new IllegalArgumentException ("Invalid integer argument '" + argument + "'", e);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 259f0da..35695c4 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -430,47 +430,46 @@
     }
 
     /**
-     * Lists all accounts of any type registered on the device.
-     * Equivalent to getAccountsByType(null).
+     * List every {@link Account} registered on the device that are managed by
+     * applications whose signatures match the caller.
      *
-     * <p>It is safe to call this method from the main thread.
+     * <p>This method can be called safely from the main thread. It is
+     * equivalent to calling <code>getAccountsByType(null)</code>.
      *
-     * <p>Clients of this method that have not been granted the
-     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
-     * will only see those accounts managed by AbstractAccountAuthenticators whose
-     * signature matches the client.
+     * <p><b>NOTE:</b> Apps declaring a {@code targetSdkVersion<=23} in their
+     * manifests will continue to behave as they did on devices that support
+     * API level 23. In particular the GET_ACCOUNTS permission is required to
+     * see all the Accounts registered with the AccountManager. See docs for
+     * this function in API level 23 for more information.
      *
-     * @return An array of {@link Account}, one for each account.  Empty
-     *     (never null) if no accounts have been added.
+     * @return Array of Accounts. The array may be empty if no accounts are
+     *     available to the caller.
      */
     @NonNull
-    @RequiresPermission(GET_ACCOUNTS)
     public Account[] getAccounts() {
-        try {
-            return mService.getAccounts(null, mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            // won't ever happen
-            throw new RuntimeException(e);
-        }
+        return getAccountsByType(null);
     }
 
     /**
      * @hide
-     * Lists all accounts of any type registered on the device for a given
-     * user id. Equivalent to getAccountsByType(null).
+     * List every {@link Account} registered on the device for a specific User
+     * that are managed by applications whose signatures match the caller.
      *
-     * <p>It is safe to call this method from the main thread.
+     * <p><b>NOTE:</b> Apps declaring a {@code targetSdkVersion<=23} in their
+     * manifests will continue to behave as they did on devices that support
+     * API level 23. In particular the GET_ACCOUNTS permission is required to
+     * see all the Accounts registered with the AccountManager for the
+     * specified userId. See docs for this function in API level 23 for more
+     * information.
      *
-     * <p>Clients of this method that have not been granted the
-     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
-     * will only see those accounts managed by AbstractAccountAuthenticators whose
-     * signature matches the client.
+     * <p>This method can be called safely from the main thread.
      *
-     * @return An array of {@link Account}, one for each account.  Empty
-     *     (never null) if no accounts have been added.
+     * @param int userId associated with the User whose accounts should be
+     *     queried.
+     * @return Array of Accounts. The array may be empty if no accounts are
+     *     available to the caller.
      */
     @NonNull
-    @RequiresPermission(GET_ACCOUNTS)
     public Account[] getAccountsAsUser(int userId) {
         try {
             return mService.getAccountsAsUser(null, userId, mContext.getOpPackageName());
@@ -501,10 +500,11 @@
     /**
      * Returns the accounts visible to the specified package, in an environment where some apps
      * are not authorized to view all accounts. This method can only be called by system apps.
+     *
      * @param type The type of accounts to return, null to retrieve all accounts
      * @param packageName The package name of the app for which the accounts are to be returned
-     * @return An array of {@link Account}, one per matching account.  Empty
-     *     (never null) if no accounts of the specified type have been added.
+     * @return Array of Accounts. The array may be empty if no accounts of th
+     *     specified type are visible to the caller.
      */
     @NonNull
     public Account[] getAccountsByTypeForPackage(String type, String packageName) {
@@ -518,29 +518,22 @@
     }
 
     /**
-     * Lists all accounts of a particular type.  The account type is a
-     * string token corresponding to the authenticator and useful domain
-     * of the account.  For example, there are types corresponding to Google
-     * and Facebook.  The exact string token to use will be published somewhere
-     * associated with the authenticator in question.
+     * List every {@link Account} of a specified type managed by applications
+     * whose signatures match the caller.
      *
-     * <p>It is safe to call this method from the main thread.
+     * <p><b>NOTE:</b> Apps declaring a {@code targetSdkVersion<=23} in their
+     * manifests will continue to behave as they did on devices that support
+     * API level 23. See docs for this function in API level 23 for more
+     * information.
      *
-     * <p>Clients of this method that have not been granted the
-     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
-     * will only see those accounts managed by AbstractAccountAuthenticators whose
-     * signature matches the client.
+     * <p>This method can be called safely from the main thread.
      *
-     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
-     * GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
-     * or signature match. See docs for this function in API level 22.
-     *
-     * @param type The type of accounts to return, null to retrieve all accounts
-     * @return An array of {@link Account}, one per matching account.  Empty
-     *     (never null) if no accounts of the specified type have been added.
+     * @param type String denoting the type of the accounts to return,
+     *        {@code null} to retrieve all accounts visible to the caller.
+     * @return An array of Accounts.  Empty (never null) if no accounts
+     *         are available to the caller.
      */
     @NonNull
-    @RequiresPermission(GET_ACCOUNTS)
     public Account[] getAccountsByType(String type) {
         return getAccountsByTypeAsUser(type, Process.myUserHandle());
     }
@@ -586,12 +579,14 @@
      * @return a future containing the label string
      * @hide
      */
+    @NonNull
     public AccountManagerFuture<String> getAuthTokenLabel(
             final String accountType, final String authTokenType,
             AccountManagerCallback<String> callback, Handler handler) {
         if (accountType == null) throw new IllegalArgumentException("accountType is null");
         if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
         return new Future2Task<String>(handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.getAuthTokenLabel(mResponse, accountType, authTokenType);
             }
@@ -617,9 +612,13 @@
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#GET_ACCOUNTS} or be a signature
-     * match with the AbstractAccountAuthenticator that manages the account.
+     * <p><b>Note:</b>The specified account must be managed by an application
+     * whose signature matches the caller.
+     *
+     * <p><b>Further note:</b>Apps targeting API level 23 or earlier will continue to
+     * behave as they did on devices that support API level 23. In particular
+     * they may still require the GET_ACCOUNTS permission. See docs for this
+     * function in API level 23.
      *
      * @param account The {@link Account} to test
      * @param features An array of the account features to check
@@ -628,18 +627,22 @@
      * @param handler {@link Handler} identifying the callback thread,
      *     null for the main thread
      * @return An {@link AccountManagerFuture} which resolves to a Boolean,
-     * true if the account exists and has all of the specified features.
+     *     true if the account exists and has all of the specified features.
+     * @throws SecurityException if the specified account is managed by an
+     *     application whose signature doesn't match the caller's signature.
      */
-    @RequiresPermission(GET_ACCOUNTS)
+    @NonNull
     public AccountManagerFuture<Boolean> hasFeatures(final Account account,
             final String[] features,
             AccountManagerCallback<Boolean> callback, Handler handler) {
         if (account == null) throw new IllegalArgumentException("account is null");
         if (features == null) throw new IllegalArgumentException("features is null");
         return new Future2Task<Boolean>(handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.hasFeatures(mResponse, account, features, mContext.getOpPackageName());
             }
+            @Override
             public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
                 if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
                     throw new AuthenticatorException("no result in response");
@@ -651,9 +654,10 @@
 
     /**
      * Lists all accounts of a type which have certain features.  The account
-     * type identifies the authenticator (see {@link #getAccountsByType}).
-     * Account features are authenticator-specific string tokens identifying
-     * boolean account properties (see {@link #hasFeatures}).
+     * type identifies the authenticator (see {@link #getAccountsByType}). Said
+     * authenticator must be in a package whose signature matches the callers
+     * package signature. Account features are authenticator-specific string tokens
+     * identifying boolean account properties (see {@link #hasFeatures}).
      *
      * <p>Unlike {@link #getAccountsByType}, this method calls the authenticator,
      * which may contact the server or do other work to check account features,
@@ -662,19 +666,14 @@
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
-     * <p>Clients of this method that have not been granted the
-     * {@link android.Manifest.permission#GET_ACCOUNTS} permission,
-     * will only see those accounts managed by AbstractAccountAuthenticators whose
-     * signature matches the client.
+     * <p><b>NOTE:</b> Apps targeting API level 23 or earlier will continue to
+     * behave as they did on devices that support API level 23. In particular
+     * they may still require the GET_ACCOUNTS permission. See docs for this
+     * function in API level 23.
      *
      * @param type The type of accounts to return, must not be null
      * @param features An array of the account features to require,
      *     may be null or empty
-     *
-     * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
-     * GET_ACCOUNTS permission is needed for those platforms, irrespective of uid
-     * or signature match. See docs for this function in API level 22.
-     *
      * @param callback Callback to invoke when the request completes,
      *     null for no callback
      * @param handler {@link Handler} identifying the callback thread,
@@ -683,16 +682,18 @@
      *     {@link Account}, one per account of the specified type which
      *     matches the requested features.
      */
-    @RequiresPermission(GET_ACCOUNTS)
+    @NonNull
     public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
             final String type, final String[] features,
             AccountManagerCallback<Account[]> callback, Handler handler) {
         if (type == null) throw new IllegalArgumentException("type is null");
         return new Future2Task<Account[]>(handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.getAccountsByFeatures(mResponse, type, features,
                         mContext.getOpPackageName());
             }
+            @Override
             public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException {
                 if (!bundle.containsKey(KEY_ACCOUNTS)) {
                     throw new AuthenticatorException("no result in response");
@@ -971,6 +972,7 @@
         if (userHandle == null)
             throw new IllegalArgumentException("userHandle is null");
         return new AmsTask(activity, handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.removeAccountAsUser(mResponse, account, activity != null,
                         userHandle.getIdentifier());
@@ -1051,7 +1053,7 @@
      * is needed for those platforms. See docs for this function in API level 22.
      *
      * @param account The account for which an auth token is to be fetched. Cannot be {@code null}.
-     * @param authTokenType The type of auth token to fetch. Cannot be {@code null}. 
+     * @param authTokenType The type of auth token to fetch. Cannot be {@code null}.
      * @return The cached auth token for this account and type, or null if
      *     no auth token is cached or the account does not exist.
      * @see #getAuthToken
@@ -1245,7 +1247,7 @@
      * tokens to access Gmail and Google Calendar for the same account.
      *
      * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
-     * USE_CREDENTIALS permission is needed for those platforms. See docs for 
+     * USE_CREDENTIALS permission is needed for those platforms. See docs for
      * this function in API level 22.
      *
      * <p>This method may be called from any thread, but the returned
@@ -1295,6 +1297,7 @@
         }
         optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
         return new AmsTask(activity, handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.getAuthToken(mResponse, account, authTokenType,
                         false /* notifyOnAuthFailure */, true /* expectActivityLaunch */,
@@ -1412,7 +1415,7 @@
      * {@link AccountManagerFuture} must not be used on the main thread.
      *
      * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
-     * USE_CREDENTIALS permission is needed for those platforms. See docs for 
+     * USE_CREDENTIALS permission is needed for those platforms. See docs for
      * this function in API level 22.
      *
      * @param account The account to fetch an auth token for
@@ -1463,6 +1466,7 @@
         }
         optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
         return new AmsTask(null, handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.getAuthToken(mResponse, account, authTokenType,
                         notifyAuthFailure, false /* expectActivityLaunch */, optionsIn);
@@ -1478,7 +1482,7 @@
      *
      * <p>This method may be called from any thread, but the returned
      * {@link AccountManagerFuture} must not be used on the main thread.
-     * 
+     *
      * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
      * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
      * this function in API level 22.
@@ -1532,6 +1536,7 @@
         optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
 
         return new AmsTask(activity, handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.addAccount(mResponse, accountType, authTokenType,
                         requiredFeatures, activity != null, optionsIn);
@@ -1556,6 +1561,7 @@
         optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
 
         return new AmsTask(activity, handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.addAccountAsUser(mResponse, accountType, authTokenType,
                         requiredFeatures, activity != null, optionsIn, userHandle.getIdentifier());
@@ -1732,6 +1738,7 @@
         if (account == null) throw new IllegalArgumentException("account is null");
         final int userId = userHandle.getIdentifier();
         return new AmsTask(activity, handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.confirmCredentialsAsUser(mResponse, account, options, activity != null,
                         userId);
@@ -1794,6 +1801,7 @@
             final Handler handler) {
         if (account == null) throw new IllegalArgumentException("account is null");
         return new AmsTask(activity, handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.updateCredentials(mResponse, account, authTokenType, activity != null,
                         options);
@@ -1847,6 +1855,7 @@
             final Handler handler) {
         if (accountType == null) throw new IllegalArgumentException("accountType is null");
         return new AmsTask(activity, handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.editProperties(mResponse, accountType, activity != null);
             }
@@ -1886,6 +1895,7 @@
             final AccountManagerFuture<Bundle> future) {
         handler = handler == null ? mMainHandler : handler;
         handler.post(new Runnable() {
+            @Override
             public void run() {
                 callback.run(future);
             }
@@ -1900,6 +1910,7 @@
         System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length);
         handler = (handler == null) ? mMainHandler : handler;
         handler.post(new Runnable() {
+            @Override
             public void run() {
                 try {
                     listener.onAccountsUpdated(accountsCopy);
@@ -1919,6 +1930,7 @@
         final Activity mActivity;
         public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) {
             super(new Callable<Bundle>() {
+                @Override
                 public Bundle call() throws Exception {
                     throw new IllegalStateException("this should never be called");
                 }
@@ -1939,6 +1951,7 @@
             return this;
         }
 
+        @Override
         protected void set(Bundle bundle) {
             // TODO: somehow a null is being set as the result of the Future. Log this
             // case to help debug where this is occurring. When this bug is fixed this
@@ -1989,16 +2002,19 @@
             throw new OperationCanceledException();
         }
 
+        @Override
         public Bundle getResult()
                 throws OperationCanceledException, IOException, AuthenticatorException {
             return internalGetResult(null, null);
         }
 
+        @Override
         public Bundle getResult(long timeout, TimeUnit unit)
                 throws OperationCanceledException, IOException, AuthenticatorException {
             return internalGetResult(timeout, unit);
         }
 
+        @Override
         protected void done() {
             if (mCallback != null) {
                 postToHandler(mHandler, mCallback, this);
@@ -2007,6 +2023,7 @@
 
         /** Handles the responses from the AccountManager */
         private class Response extends IAccountManagerResponse.Stub {
+            @Override
             public void onResult(Bundle bundle) {
                 Intent intent = bundle.getParcelable(KEY_INTENT);
                 if (intent != null && mActivity != null) {
@@ -2026,6 +2043,7 @@
                 }
             }
 
+            @Override
             public void onError(int code, String message) {
                 if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED
                         || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) {
@@ -2046,6 +2064,7 @@
 
         public BaseFutureTask(Handler handler) {
             super(new Callable<T>() {
+                @Override
                 public T call() throws Exception {
                     throw new IllegalStateException("this should never be called");
                 }
@@ -2072,6 +2091,7 @@
         }
 
         protected class Response extends IAccountManagerResponse.Stub {
+            @Override
             public void onResult(Bundle bundle) {
                 try {
                     T result = bundleToResult(bundle);
@@ -2088,6 +2108,7 @@
                 onError(ERROR_CODE_INVALID_RESPONSE, "no result in response");
             }
 
+            @Override
             public void onError(int code, String message) {
                 if (code == ERROR_CODE_CANCELED || code == ERROR_CODE_USER_RESTRICTED
                         || code == ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE) {
@@ -2109,9 +2130,11 @@
             mCallback = callback;
         }
 
+        @Override
         protected void done() {
             if (mCallback != null) {
                 postRunnableToHandler(new Runnable() {
+                    @Override
                     public void run() {
                         mCallback.run(Future2Task.this);
                     }
@@ -2162,11 +2185,13 @@
             throw new OperationCanceledException();
         }
 
+        @Override
         public T getResult()
                 throws OperationCanceledException, IOException, AuthenticatorException {
             return internalGetResult(null, null);
         }
 
+        @Override
         public T getResult(long timeout, TimeUnit unit)
                 throws OperationCanceledException, IOException, AuthenticatorException {
             return internalGetResult(timeout, unit);
@@ -2218,9 +2243,11 @@
         final AccountManagerCallback<Bundle> mMyCallback;
         private volatile int mNumAccounts = 0;
 
+        @Override
         public void doWork() throws RemoteException {
             getAccountsByTypeAndFeatures(mAccountType, mFeatures,
                     new AccountManagerCallback<Account[]>() {
+                        @Override
                         public void run(AccountManagerFuture<Account[]> future) {
                             Account[] accounts;
                             try {
@@ -2271,6 +2298,7 @@
                                 if (mActivity != null) {
                                     IAccountManagerResponse chooseResponse =
                                             new IAccountManagerResponse.Stub() {
+                                        @Override
                                         public void onResult(Bundle value) throws RemoteException {
                                             Account account = new Account(
                                                     value.getString(KEY_ACCOUNT_NAME),
@@ -2279,6 +2307,7 @@
                                                     mActivity, mMyCallback, mHandler);
                                         }
 
+                                        @Override
                                         public void onError(int errorCode, String errorMessage)
                                                 throws RemoteException {
                                             mResponse.onError(errorCode, errorMessage);
@@ -2311,6 +2340,7 @@
                         }}, mHandler);
         }
 
+        @Override
         public void run(AccountManagerFuture<Bundle> future) {
             try {
                 final Bundle result = future.getResult();
@@ -2531,6 +2561,7 @@
      * in mAccountsUpdatedListeners.
      */
     private final BroadcastReceiver mAccountsChangedBroadcastReceiver = new BroadcastReceiver() {
+        @Override
         public void onReceive(final Context context, final Intent intent) {
             final Account[] accounts = getAccounts();
             // send the result to the listeners
@@ -2851,6 +2882,25 @@
             final Activity activity,
             AccountManagerCallback<Bundle> callback,
             Handler handler) {
+        return finishSessionAsUser(
+                sessionBundle,
+                activity,
+                Process.myUserHandle(),
+                callback,
+                handler);
+    }
+
+    /**
+     * @see #finishSession
+     * @hide
+     */
+    @SystemApi
+    public AccountManagerFuture<Bundle> finishSessionAsUser(
+            final Bundle sessionBundle,
+            final Activity activity,
+            final UserHandle userHandle,
+            AccountManagerCallback<Bundle> callback,
+            Handler handler) {
         if (sessionBundle == null) {
             throw new IllegalArgumentException("sessionBundle is null");
         }
@@ -2862,7 +2912,12 @@
         return new AmsTask(activity, handler, callback) {
             @Override
             public void doWork() throws RemoteException {
-                mService.finishSession(mResponse, sessionBundle, activity != null, appInfo);
+                mService.finishSessionAsUser(
+                        mResponse,
+                        sessionBundle,
+                        activity != null,
+                        appInfo,
+                        userHandle.getIdentifier());
             }
         }.start();
     }
@@ -2898,12 +2953,14 @@
         }
 
         return new Future2Task<Boolean>(handler, callback) {
+            @Override
             public void doWork() throws RemoteException {
                 mService.isCredentialsUpdateSuggested(
                         mResponse,
                         account,
                         statusToken);
             }
+            @Override
             public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
                 if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
                     throw new AuthenticatorException("no result in response");
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 39dedf4..7199288 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -92,9 +92,9 @@
     void startUpdateCredentialsSession(in IAccountManagerResponse response, in Account account,
         String authTokenType, boolean expectActivityLaunch, in Bundle options);
 
-    /* Finish session started by startAddAccountSession(...) or startUpdateCredentialsSession(...) */
-    void finishSession(in IAccountManagerResponse response, in Bundle sessionBundle,
-        boolean expectActivityLaunch, in Bundle appInfo);
+    /* Finish session started by startAddAccountSession(...) or startUpdateCredentialsSession(...) for user */
+    void finishSessionAsUser(in IAccountManagerResponse response, in Bundle sessionBundle,
+        boolean expectActivityLaunch, in Bundle appInfo, int userId);
 
     /* Check if an account exists on any user on the device. */
     boolean someUserHasAccount(in Account account);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e312596..11154f2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1267,6 +1267,15 @@
         mCalled = true;
     }
 
+    void setVoiceInteractor(IVoiceInteractor voiceInteractor) {
+        if (voiceInteractor == null) {
+            mVoiceInteractor = null;
+        } else {
+            mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
+                    Looper.myLooper());
+        }
+    }
+
     /**
      * Check whether this activity is running as part of a voice interaction with the user.
      * If true, it should perform its interaction with the user through the
@@ -1301,6 +1310,62 @@
     }
 
     /**
+     * Queries whether the currently enabled voice interaction service supports returning
+     * a voice interactor for use by the activity. This is valid only for the duration of the
+     * activity.
+     *
+     * @return whether the current voice interaction service supports local voice interaction
+     */
+    public boolean isLocalVoiceInteractionSupported() {
+        try {
+            return ActivityManagerNative.getDefault().supportsLocalVoiceInteraction();
+        } catch (RemoteException re) {
+        }
+        return false;
+    }
+
+    /**
+     * Starts a local voice interaction session. When ready,
+     * {@link #onLocalVoiceInteractionStarted()} is called. You can pass a bundle of private options
+     * to the registered voice interaction service.
+     * @param privateOptions a Bundle of private arguments to the current voice interaction service
+     */
+    public void startLocalVoiceInteraction(Bundle privateOptions) {
+        try {
+            ActivityManagerNative.getDefault().startLocalVoiceInteraction(mToken, privateOptions);
+        } catch (RemoteException re) {
+        }
+    }
+
+    /**
+     * Callback to indicate that {@link #startLocalVoiceInteraction(Bundle)} has resulted in a
+     * voice interaction session being started. You can now retrieve a voice interactor using
+     * {@link #getVoiceInteractor()}.
+     */
+    public void onLocalVoiceInteractionStarted() {
+        Log.i(TAG, "onLocalVoiceInteractionStarted! " + getVoiceInteractor());
+    }
+
+    /**
+     * Callback to indicate that the local voice interaction has stopped for some
+     * reason.
+     */
+    public void onLocalVoiceInteractionStopped() {
+        Log.i(TAG, "onLocalVoiceInteractionStopped :( " + getVoiceInteractor());
+    }
+
+    /**
+     * Request to terminate the current voice interaction that was previously started
+     * using {@link #startLocalVoiceInteraction(Bundle)}.
+     */
+    public void stopLocalVoiceInteraction() {
+        try {
+            ActivityManagerNative.getDefault().stopLocalVoiceInteraction(mToken);
+        } catch (RemoteException re) {
+        }
+    }
+
+    /**
      * This is called for activities that set launchMode to "singleTop" in
      * their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP}
      * flag when calling {@link #startActivity}.  In either case, when the
@@ -2248,7 +2313,7 @@
      * <p>In order to use a Toolbar within the Activity's window content the application
      * must not request the window feature {@link Window#FEATURE_ACTION_BAR FEATURE_ACTION_BAR}.</p>
      *
-     * @param toolbar Toolbar to set as the Activity's action bar
+     * @param toolbar Toolbar to set as the Activity's action bar, or {@code null} to clear it
      */
     public void setActionBar(@Nullable Toolbar toolbar) {
         final ActionBar ab = getActionBar();
@@ -2267,10 +2332,17 @@
             ab.onDestroy();
         }
 
-        ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this);
-        mActionBar = tbab;
-        mWindow.setCallback(tbab.getWrappedWindowCallback());
-        mActionBar.invalidateOptionsMenu();
+        if (toolbar != null) {
+            final ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this);
+            mActionBar = tbab;
+            mWindow.setCallback(tbab.getWrappedWindowCallback());
+        } else {
+            mActionBar = null;
+            // Re-set the original window callback since we may have already set a Toolbar wrapper
+            mWindow.setCallback(this);
+        }
+
+        invalidateOptionsMenu();
     }
 
     /**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 2dc4fb9..420bf31 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -85,16 +85,16 @@
     private final Context mContext;
     private final Handler mHandler;
 
+    /**
+     * Defines acceptable types of bugreports.
+     * @hide
+     */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
             BUGREPORT_OPTION_FULL,
             BUGREPORT_OPTION_INTERACTIVE,
             BUGREPORT_OPTION_REMOTE
     })
-    /**
-     * Defines acceptable types of bugreports.
-     * @hide
-     */
     public @interface BugreportMode {}
     /**
      * Takes a bugreport without user interference (and hence causing less
@@ -608,6 +608,14 @@
         public static boolean resizeStackWithLaunchBounds(int stackId) {
             return stackId == PINNED_STACK_ID;
         }
+
+        /**
+         * Returns true if any visible windows belonging to apps in this stack should be kept on
+         * screen when the app is killed due to something like the low memory killer.
+         */
+        public static boolean keepVisibleDeadAppWindowOnScreen(int stackId) {
+            return stackId != PINNED_STACK_ID;
+        }
     }
 
     /**
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 373a23f..4fa654f 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -18,6 +18,10 @@
 
 import android.annotation.NonNull;
 import android.content.ComponentName;
+import android.os.IBinder;
+import android.service.voice.IVoiceInteractionSession;
+
+import com.android.internal.app.IVoiceInteractor;
 
 /**
  * Activity manager local system service interface.
@@ -64,4 +68,8 @@
      * @param userId The user being cleaned up.
      */
     public abstract void onUserRemoved(int userId);
+
+    public abstract void onLocalVoiceInteractionStarted(IBinder callingActivity,
+            IVoiceInteractionSession mSession,
+            IVoiceInteractor mInteractor);
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 63b6825..42ff8e8 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -315,6 +315,34 @@
             return true;
         }
 
+        case START_LOCAL_VOICE_INTERACTION_TRANSACTION:
+        {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            Bundle options = data.readBundle();
+            startLocalVoiceInteraction(token, options);
+            reply.writeNoException();
+            return true;
+        }
+
+        case STOP_LOCAL_VOICE_INTERACTION_TRANSACTION:
+        {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            stopLocalVoiceInteraction(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION:
+        {
+            data.enforceInterface(IActivityManager.descriptor);
+            boolean result = supportsLocalVoiceInteraction();
+            reply.writeNoException();
+            reply.writeInt(result? 1 : 0);
+            return true;
+        }
+
         case START_NEXT_MATCHING_ACTIVITY_TRANSACTION:
         {
             data.enforceInterface(IActivityManager.descriptor);
@@ -3136,6 +3164,43 @@
         data.recycle();
         return result;
     }
+
+    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(callingActivity);
+        data.writeBundle(options);
+        mRemote.transact(START_LOCAL_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
+        reply.readException();
+        reply.recycle();
+        data.recycle();
+    }
+
+    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(callingActivity);
+        mRemote.transact(STOP_LOCAL_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
+        reply.readException();
+        reply.recycle();
+        data.recycle();
+    }
+
+    public boolean supportsLocalVoiceInteraction() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int result = reply.readInt();
+        reply.recycle();
+        data.recycle();
+        return result != 0;
+    }
+
     public boolean startNextMatchingActivity(IBinder callingActivity,
             Intent intent, Bundle options) throws RemoteException {
         Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7b01953..1e7457c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1254,6 +1254,15 @@
                 throws RemoteException {
             sendMessage(H.PICTURE_IN_PICTURE_MODE_CHANGED, token, pipMode ? 1 : 0);
         }
+
+        @Override
+        public void scheduleLocalVoiceInteractionStarted(IBinder token,
+                IVoiceInteractor voiceInteractor) throws RemoteException {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = token;
+            args.arg2 = voiceInteractor;
+            sendMessage(H.LOCAL_VOICE_INTERACTION_STARTED, args);
+        }
     }
 
     private int getLifecycleSeq() {
@@ -1317,6 +1326,7 @@
         public static final int STOP_BINDER_TRACKING_AND_DUMP = 151;
         public static final int MULTI_WINDOW_MODE_CHANGED = 152;
         public static final int PICTURE_IN_PICTURE_MODE_CHANGED = 153;
+        public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
 
         String codeToString(int code) {
             if (DEBUG_MESSAGES) {
@@ -1372,6 +1382,7 @@
                     case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
                     case MULTI_WINDOW_MODE_CHANGED: return "MULTI_WINDOW_MODE_CHANGED";
                     case PICTURE_IN_PICTURE_MODE_CHANGED: return "PICTURE_IN_PICTURE_MODE_CHANGED";
+                    case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED";
                 }
             }
             return Integer.toString(code);
@@ -1621,6 +1632,10 @@
                 case PICTURE_IN_PICTURE_MODE_CHANGED:
                     handlePictureInPictureModeChanged((IBinder) msg.obj, msg.arg1 == 1);
                     break;
+                case LOCAL_VOICE_INTERACTION_STARTED:
+                    handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
+                            (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
+                    break;
             }
             Object obj = msg.obj;
             if (obj instanceof SomeArgs) {
@@ -2878,6 +2893,19 @@
         }
     }
 
+    private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) {
+        final ActivityClientRecord r = mActivities.get(token);
+        if (r != null) {
+            r.voiceInteractor = interactor;
+            r.activity.setVoiceInteractor(interactor);
+            if (interactor == null) {
+                r.activity.onLocalVoiceInteractionStopped();
+            } else {
+                r.activity.onLocalVoiceInteractionStarted();
+            }
+        }
+    }
+
     private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
 
     /**
@@ -4888,8 +4916,10 @@
 
         /*
          * Initialize the default locales in this process for the reasons we set the time zone.
+         *
+         * We do this through ResourcesManager, since we need to do locale negotiation.
          */
-        LocaleList.setDefault(data.config.getLocales());
+        mResourcesManager.setDefaultLocalesLocked(data.config.getLocales());
 
         /*
          * Update the system configuration since its preloaded and might not
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 5951c8d..9be7f23 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -425,6 +425,16 @@
             return true;
         }
 
+        case SCHEDULE_LOCAL_VOICE_INTERACTION_STARTED_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            IBinder token = data.readStrongBinder();
+            IVoiceInteractor voiceInteractor = IVoiceInteractor.Stub.asInterface(
+                    data.readStrongBinder());
+            scheduleLocalVoiceInteractionStarted(token, voiceInteractor);
+            return true;
+        }
+
         case PROFILER_CONTROL_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
@@ -1101,6 +1111,17 @@
         data.recycle();
     }
 
+    public final void scheduleLocalVoiceInteractionStarted(IBinder token,
+            IVoiceInteractor voiceInteractor) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeStrongBinder(token);
+        data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);
+        mRemote.transact(SCHEDULE_LOCAL_VOICE_INTERACTION_STARTED_TRANSACTION, data, null,
+                IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
+
     public void updateTimeZone() throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5bb2cf5..22de2ff 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -591,6 +591,12 @@
 
     public boolean isAppForeground(int uid) throws RemoteException;
 
+    public void startLocalVoiceInteraction(IBinder token, Bundle options) throws RemoteException;
+
+    public void stopLocalVoiceInteraction(IBinder token) throws RemoteException;
+
+    public boolean supportsLocalVoiceInteraction() throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -963,4 +969,7 @@
     int GET_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 360;
     int CLEAR_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 361;
     int IS_APP_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 362;
+    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;
 }
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index dc67026..6d64bd0 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -154,6 +154,7 @@
     void stopBinderTrackingAndDump(FileDescriptor fd) throws RemoteException;
     void scheduleMultiWindowModeChanged(IBinder token, boolean multiWindowMode) throws RemoteException;
     void schedulePictureInPictureModeChanged(IBinder token, boolean multiWindowMode) throws RemoteException;
+    void scheduleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor voiceInteractor) throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
 
@@ -216,4 +217,5 @@
     int STOP_BINDER_TRACKING_AND_DUMP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+57;
     int SCHEDULE_MULTI_WINDOW_MODE_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+58;
     int SCHEDULE_PICTURE_IN_PICTURE_MODE_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+59;
+    int SCHEDULE_LOCAL_VOICE_INTERACTION_STARTED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+60;
 }
diff --git a/core/java/android/app/IBackupAgent.aidl b/core/java/android/app/IBackupAgent.aidl
index fe8e228..eda9603 100644
--- a/core/java/android/app/IBackupAgent.aidl
+++ b/core/java/android/app/IBackupAgent.aidl
@@ -105,6 +105,27 @@
     void doMeasureFullBackup(int token, IBackupManager callbackBinder);
 
     /**
+     * Tells the application agent that the backup data size exceeded current transport quota.
+     * Later calls to {@link #onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)}
+     * and {@link #onFullBackup(FullBackupDataOutput)} could use this information
+     * to reduce backup size under the limit.
+     * However, the quota can change, so do not assume that the value passed in here is absolute,
+     * similarly all subsequent backups should not be restricted to this size.
+     * This callback will be invoked before data has been put onto the wire in a preflight check,
+     * so it is relatively inexpensive to hit your quota.
+     * Apps that hit quota repeatedly without dealing with it can be subject to having their backup
+     * schedule reduced.
+     * The {@code quotaBytes} is a loose guideline b/c of metadata added by the backupmanager
+     * so apps should be more aggressive in trimming their backup set.
+     *
+     * @param backupDataBytes Expected or already processed amount of data.
+     *                        Could be less than total backup size if backup process was interrupted
+     *                        before finish of processing all backup data.
+     * @param quotaBytes Current amount of backup data that is allowed for the app.
+     */
+    void doQuotaExceeded(long backupDataBytes, long quotaBytes);
+
+    /**
      * Restore a single "file" to the application.  The file was typically obtained from
      * a full-backup dataset.  The agent reads 'size' bytes of file content
      * from the provided file descriptor.
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 368b8ef..3288cd9 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -48,13 +48,12 @@
     boolean areNotificationsEnabledForPackage(String pkg, int uid);
 
     ParceledListSlice getTopics(String pkg, int uid);
-    void setTopicVisibilityOverride(String pkg, int uid, in Notification.Topic topic, int visibility);
-    int getTopicVisibilityOverride(String pkg, int uid, in Notification.Topic topic);
-    void setTopicPriority(String pkg, int uid, in Notification.Topic topic, int priority);
-    int getTopicPriority(String pkg, int uid, in Notification.Topic topic);
-    void setTopicImportance(String pkg, int uid, in Notification.Topic topic, int importance);
-    int getTopicImportance(String pkg, int uid, in Notification.Topic topic);
-    void setAppImportance(String pkg, int uid, int importance);
+    void setVisibilityOverride(String pkg, int uid, in Notification.Topic topic, int visibility);
+    int getVisibilityOverride(String pkg, int uid, in Notification.Topic topic);
+    void setPriority(String pkg, int uid, in Notification.Topic topic, int priority);
+    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);
 
     // 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 560e22a..fa11234 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -23,4 +23,11 @@
 
     /** Called whenever an Activity is moved to the pinned stack from another stack. */
     void onActivityPinned();
+
+    /**
+     * Called whenever IActivityManager.startActivity is called on an activity that is already
+     * running in the pinned stack and the activity is not actually started, but the task is either
+     * brought to the front or a new Intent is delivered to it.
+     */
+    void onPinnedActivityRestartAttempt();
 }
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index ccba250..7a0e7f6 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -28,37 +28,47 @@
 
     /**
      * Set the wallpaper.
+     *
+     * If 'extras' is non-null, on successful return it will contain:
+     *   EXTRA_SET_WALLPAPER_ID : integer ID that the new wallpaper will have
+     *
+     * 'which' is some combination of:
+     *   FLAG_SET_SYSTEM
+     *   FLAG_SET_LOCK
      */
-    ParcelFileDescriptor setWallpaper(String name, in String callingPackage);
+    ParcelFileDescriptor setWallpaper(String name, in String callingPackage,
+            out Bundle extras, int which);
     
     /**
-     * Set the live wallpaper.
+     * Set the live wallpaper. This only affects the system wallpaper.
      */
     void setWallpaperComponentChecked(in ComponentName name, in String callingPackage);
 
     /**
-     * Set the live wallpaper.
+     * Set the live wallpaper. This only affects the system wallpaper.
      */
     void setWallpaperComponent(in ComponentName name);
 
     /**
-     * Get the wallpaper.
+     * Get the system wallpaper.
      */
     ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
             out Bundle outParams);
     
     /**
-     * Get information about a live wallpaper.
+     * If the current system wallpaper is a live wallpaper component, return the
+     * information about that wallpaper.  Otherwise, if it is a static image,
+     * simply return null.
      */
     WallpaperInfo getWallpaperInfo();
     
     /**
-     * Clear the wallpaper.
+     * Clear the system wallpaper.
      */
     void clearWallpaper(in String callingPackage);
 
     /**
-     * Return whether there is a wallpaper set with the given name.
+     * Return whether the current system wallpaper has the given name.
      */
     boolean hasNamedWallpaper(String name);
 
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 855b21e..1e22bef 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -366,7 +366,7 @@
                     }
                 }
 
-                String libraryPermittedPath = mAppDir + File.pathSeparator + mDataDir;
+                String libraryPermittedPath = mDataDir;
                 boolean isBundledApp = false;
 
                 if (mApplicationInfo.isSystemApp()) {
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 260216c..94e584e 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -35,6 +35,9 @@
 import android.view.DisplayAdjustments;
 
 import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
 
 /** @hide */
 public class ResourcesManager {
@@ -42,11 +45,15 @@
     private static final boolean DEBUG = false;
 
     private static ResourcesManager sResourcesManager;
-    private final ArrayMap<ResourcesKey, WeakReference<Resources> > mActiveResources =
+    private final ArrayMap<ResourcesKey, WeakReference<Resources>> mActiveResources =
             new ArrayMap<>();
     private final ArrayMap<Pair<Integer, DisplayAdjustments>, WeakReference<Display>> mDisplays =
             new ArrayMap<>();
 
+    private String[] mSystemLocales = {};
+    private final HashSet<String> mNonSystemLocales = new HashSet<String>();
+    private boolean mHasNonSystemLocales = false;
+
     CompatibilityInfo mResCompatibilityInfo;
 
     Configuration mResConfiguration;
@@ -165,6 +172,8 @@
                 ? new Configuration(overrideConfiguration) : null;
         ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfigCopy, scale);
         Resources r;
+        final boolean findSystemLocales;
+        final boolean hasNonSystemLocales;
         synchronized (this) {
             // Resources is app scale dependent.
             if (DEBUG) Slog.w(TAG, "getTopLevelResources: " + resDir + " / " + scale);
@@ -178,6 +187,8 @@
                         + " key=" + key + " overrideConfig=" + overrideConfiguration);
                 return r;
             }
+            findSystemLocales = (mSystemLocales.length == 0);
+            hasNonSystemLocales = mHasNonSystemLocales;
         }
 
         //if (r != null) {
@@ -243,6 +254,18 @@
         if (DEBUG) Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
                 + r.getConfiguration() + " appScale=" + r.getCompatibilityInfo().applicationScale);
 
+        final String[] systemLocales = (
+                findSystemLocales ?
+                AssetManager.getSystem().getLocales() :
+                null);
+        final String[] nonSystemLocales = assets.getNonSystemLocales();
+        // Avoid checking for non-pseudo-locales if we already know there were some from a previous
+        // Resources. The default value (for when hasNonSystemLocales is true) doesn't matter,
+        // since mHasNonSystemLocales will also be true, and thus isPseudoLocalesOnly would not be
+        // able to affect mHasNonSystemLocales.
+        final boolean isPseudoLocalesOnly = hasNonSystemLocales ||
+                LocaleList.isPseudoLocalesOnly(nonSystemLocales);
+
         synchronized (this) {
             WeakReference<Resources> wr = mActiveResources.get(key);
             Resources existing = wr != null ? wr.get() : null;
@@ -255,11 +278,30 @@
 
             // XXX need to remove entries when weak references go away
             mActiveResources.put(key, new WeakReference<>(r));
+            if (mSystemLocales.length == 0) {
+                mSystemLocales = systemLocales;
+            }
+            mNonSystemLocales.addAll(Arrays.asList(nonSystemLocales));
+            mHasNonSystemLocales = mHasNonSystemLocales || !isPseudoLocalesOnly;
             if (DEBUG) Slog.v(TAG, "mActiveResources.size()=" + mActiveResources.size());
             return r;
         }
     }
 
+    /* package */ void setDefaultLocalesLocked(LocaleList locales) {
+        final int bestLocale;
+        if (mHasNonSystemLocales) {
+            bestLocale = locales.getFirstMatchIndexWithEnglishSupported(mNonSystemLocales);
+        } else {
+            // We fallback to system locales if there was no locale specifically supported by the
+            // assets. This is to properly support apps that only rely on the shared system assets
+            // and don't need assets of their own.
+            bestLocale = locales.getFirstMatchIndexWithEnglishSupported(mSystemLocales);
+        }
+        // set it for Java, this also affects newly created Resources
+        LocaleList.setDefault(locales, bestLocale);
+    }
+
     final boolean applyConfigurationToResourcesLocked(Configuration config,
             CompatibilityInfo compat) {
         if (mResConfiguration == null) {
@@ -283,13 +325,28 @@
                     | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
         }
 
-        // set it for java, this also affects newly created Resources
-        final LocaleList localeList = config.getLocales();
-        if (!localeList.isEmpty()) {
-            LocaleList.setDefault(localeList);
+        Configuration localeAdjustedConfig = config;
+        final LocaleList configLocales = config.getLocales();
+        if (!configLocales.isEmpty()) {
+            setDefaultLocalesLocked(configLocales);
+            final LocaleList adjustedLocales = LocaleList.getAdjustedDefault();
+            if (adjustedLocales != configLocales) { // has the same result as .equals() in this case
+                // The first locale in the list was not chosen. So we create a modified
+                // configuration with the adjusted locales (which moves the chosen locale to the
+                // front).
+                localeAdjustedConfig = new Configuration();
+                localeAdjustedConfig.setTo(config);
+                localeAdjustedConfig.setLocales(adjustedLocales);
+                // Also adjust the locale list in mResConfiguration, so that the Resources created
+                // later would have the same locale list.
+                if (!mResConfiguration.getLocales().equals(adjustedLocales)) {
+                    mResConfiguration.setLocales(adjustedLocales);
+                    changes |= ActivityInfo.CONFIG_LOCALE;
+                }
+            }
         }
 
-        Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
+        Resources.updateSystemConfiguration(localeAdjustedConfig, defaultDisplayMetrics, compat);
 
         ApplicationPackageManager.configurationChanged();
         //Slog.i(TAG, "Configuration changed in " + currentPackageName());
@@ -301,7 +358,7 @@
             Resources r = mActiveResources.valueAt(i).get();
             if (r != null) {
                 if (DEBUG || DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
-                        + r + " config to: " + config);
+                        + r + " config to: " + localeAdjustedConfig);
                 int displayId = key.mDisplayId;
                 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
                 DisplayMetrics dm = defaultDisplayMetrics;
@@ -310,7 +367,7 @@
                     if (tmpConfig == null) {
                         tmpConfig = new Configuration();
                     }
-                    tmpConfig.setTo(config);
+                    tmpConfig.setTo(localeAdjustedConfig);
                     if (!isDefaultDisplay) {
                         dm = getDisplayMetricsLocked(displayId);
                         applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
@@ -320,7 +377,7 @@
                     }
                     r.updateConfiguration(tmpConfig, dm, compat);
                 } else {
-                    r.updateConfiguration(config, dm, compat);
+                    r.updateConfiguration(localeAdjustedConfig, dm, compat);
                 }
                 //Slog.i(TAG, "Updated app resources " + v.getKey()
                 //        + " " + r + ": " + r.getConfiguration());
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index f3b1175..5eed781 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import com.android.internal.app.IAppOpsService;
+import com.android.internal.app.ISoundTriggerService;
 import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.os.IDropBoxManagerService;
 
@@ -61,6 +62,7 @@
 import android.media.midi.MidiManager;
 import android.media.projection.MediaProjectionManager;
 import android.media.session.MediaSessionManager;
+import android.media.soundtrigger.SoundTriggerManager;
 import android.media.tv.ITvInputManager;
 import android.media.tv.TvInputManager;
 import android.net.ConnectivityManager;
@@ -82,11 +84,10 @@
 import android.net.wifi.nan.WifiNanManager;
 import android.net.wifi.p2p.IWifiP2pManager;
 import android.net.wifi.p2p.WifiP2pManager;
-import android.net.wifi.passpoint.IWifiPasspointManager;
-import android.net.wifi.passpoint.WifiPasspointManager;
 import android.nfc.NfcManager;
 import android.os.BatteryManager;
 import android.os.DropBoxManager;
+import android.os.HardwarePropertiesManager;
 import android.os.IBinder;
 import android.os.IPowerManager;
 import android.os.IUserManager;
@@ -483,15 +484,6 @@
                 return new WifiManager(ctx.getOuterContext(), service);
             }});
 
-        registerService(Context.WIFI_PASSPOINT_SERVICE, WifiPasspointManager.class,
-                new CachedServiceFetcher<WifiPasspointManager>() {
-            @Override
-            public WifiPasspointManager createService(ContextImpl ctx) {
-                IBinder b = ServiceManager.getService(Context.WIFI_PASSPOINT_SERVICE);
-                IWifiPasspointManager service = IWifiPasspointManager.Stub.asInterface(b);
-                return new WifiPasspointManager(ctx.getOuterContext(), service);
-            }});
-
         registerService(Context.WIFI_P2P_SERVICE, WifiP2pManager.class,
                 new StaticServiceFetcher<WifiP2pManager>() {
             @Override
@@ -718,6 +710,22 @@
             public RadioManager createService(ContextImpl ctx) {
                 return new RadioManager(ctx);
             }});
+
+        registerService(Context.HARDWARE_PROPERTIES_SERVICE, HardwarePropertiesManager.class,
+                new CachedServiceFetcher<HardwarePropertiesManager>() {
+            @Override
+            public HardwarePropertiesManager createService(ContextImpl ctx) {
+                return new HardwarePropertiesManager();
+            }});
+
+        registerService(Context.SOUND_TRIGGER_SERVICE, SoundTriggerManager.class,
+                new CachedServiceFetcher<SoundTriggerManager>() {
+            @Override
+            public SoundTriggerManager createService(ContextImpl ctx) {
+                IBinder b = ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE);
+                Log.i(TAG, "Creating new instance of SoundTriggerManager object.");
+                return new SoundTriggerManager(ctx, ISoundTriggerService.Stub.asInterface(b));
+            }});
     }
 
     /**
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 5b5bba4..f103576 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.IntDef;
 import android.annotation.RawRes;
 import android.annotation.SystemApi;
 import android.content.ComponentName;
@@ -60,6 +61,8 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -144,7 +147,33 @@
      * and y arguments are the location of the drop.
      */
     public static final String COMMAND_DROP = "android.home.drop";
-    
+
+    /**
+     * Extra passed back from setWallpaper() giving the new wallpaper's assigned ID.
+     * @hide
+     */
+    public static final String EXTRA_NEW_WALLPAPER_ID = "android.service.wallpaper.extra.ID";
+
+    // flags for which kind of wallpaper to set
+
+    /** @hide */
+    @IntDef(flag = true, value = {
+            FLAG_SET_SYSTEM,
+            FLAG_SET_LOCK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SetWallpaperFlags {}
+
+    /**
+     * Flag: use the supplied imagery as the general system wallpaper.
+     */
+    public static final int FLAG_SET_SYSTEM = 1 << 0;
+
+    /**
+     * Flag: use the supplied imagery as the lock-screen wallpaper.
+     */
+    public static final int FLAG_SET_LOCK = 1 << 1;
+
     private final Context mContext;
     
     /**
@@ -717,20 +746,41 @@
      * wallpaper.
      */
     public void setResource(@RawRes int resid) throws IOException {
+        setResource(resid, FLAG_SET_SYSTEM);
+    }
+
+    /**
+     * Version of {@link #setResource(int)} that takes an optional Bundle for returning
+     * metadata about the operation to the caller.
+     *
+     * @param resid
+     * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
+     *
+     * @see #FLAG_SET_LOCK
+     * @see #FLAG_SET_SYSTEM
+     *
+     * @return An integer ID assigned to the newly active wallpaper; or zero on failure.
+     *
+     * @throws IOException
+     */
+    public int setResource(@RawRes int resid, @SetWallpaperFlags int which)
+            throws IOException {
         if (sGlobals.mService == null) {
             Log.w(TAG, "WallpaperService not running");
-            return;
+            return 0;
         }
+        final Bundle result = new Bundle();
         try {
             Resources resources = mContext.getResources();
             /* Set the wallpaper to the default values */
             ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(
-                    "res:" + resources.getResourceName(resid), mContext.getOpPackageName());
+                    "res:" + resources.getResourceName(resid),
+                    mContext.getOpPackageName(), result, which);
             if (fd != null) {
                 FileOutputStream fos = null;
                 try {
                     fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
-                    setWallpaper(resources.openRawResource(resid), fos);
+                    copyStreamToWallpaperFile(resources.openRawResource(resid), fos);
                 } finally {
                     IoUtils.closeQuietly(fos);
                 }
@@ -738,6 +788,7 @@
         } catch (RemoteException e) {
             // Ignore
         }
+        return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
     }
 
     /**
@@ -753,7 +804,7 @@
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#SET_WALLPAPER}.
      *
-     * @param bitmap The bitmap to save.
+     * @param bitmap The bitmap to be used as the new system wallpaper.
      *
      * @throws IOException If an error occurs when attempting to set the wallpaper
      *     to the provided image.
@@ -775,42 +826,72 @@
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#SET_WALLPAPER}.
      *
-     * @param fullImage A bitmap that will supply the wallpaper imagery. 
+     * @param fullImage A bitmap that will supply the wallpaper imagery.
      * @param visibleCropHint The rectangular subregion of {@code fullImage} that should be
      *     displayed as wallpaper.  Passing {@code null} for this parameter means that
      *     the full image should be displayed if possible given the image's and device's
-     *     aspect ratios, etc. 
+     *     aspect ratios, etc.
      * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
      *     image for restore to a future device; {@code false} otherwise.
      *
+     * @return An integer ID assigned to the newly active wallpaper; or zero on failure.
+     *
      * @throws IOException If an error occurs when attempting to set the wallpaper
      *     to the provided image.
      * @throws IllegalArgumentException If the {@code visibleCropHint} rectangle is
      *     empty or invalid.
      */
-    public void setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup)
+    public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup)
+            throws IOException {
+        return setBitmap(fullImage, visibleCropHint, allowBackup, FLAG_SET_SYSTEM);
+    }
+
+    /**
+    /**
+     * Version of {@link #setBitmap(Bitmap, Rect, boolean)} that allows the caller
+     * to specify which of the supported wallpaper categories to set.
+     *
+     * @param fullImage A bitmap that will supply the wallpaper imagery.
+     * @param visibleCropHint The rectangular subregion of {@code fullImage} that should be
+     *     displayed as wallpaper.  Passing {@code null} for this parameter means that
+     *     the full image should be displayed if possible given the image's and device's
+     *     aspect ratios, etc.
+     * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
+     *     image for restore to a future device; {@code false} otherwise.
+     * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
+     *
+     * @see #FLAG_SET_LOCK_WALLPAPER
+     * @see #FLAG_SET_SYSTEM_WALLPAPER
+     *
+     * @return An integer ID assigned to the newly active wallpaper; or zero on failure.
+     *
+     * @throws IOException
+     */
+    public int setBitmap(Bitmap fullImage, Rect visibleCropHint,
+            boolean allowBackup, @SetWallpaperFlags int which)
             throws IOException {
         validateRect(visibleCropHint);
         if (sGlobals.mService == null) {
             Log.w(TAG, "WallpaperService not running");
-            return;
+            return 0;
         }
+        final Bundle result = new Bundle();
         try {
             ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,
-                    mContext.getOpPackageName());
-            if (fd == null) {
-                return;
-            }
-            FileOutputStream fos = null;
-            try {
-                fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
-                fullImage.compress(Bitmap.CompressFormat.PNG, 90, fos);
-            } finally {
-                IoUtils.closeQuietly(fos);
+                    mContext.getOpPackageName(), result, which);
+            if (fd != null) {
+                FileOutputStream fos = null;
+                try {
+                    fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
+                    fullImage.compress(Bitmap.CompressFormat.PNG, 90, fos);
+                } finally {
+                    IoUtils.closeQuietly(fos);
+                }
             }
         } catch (RemoteException e) {
             // Ignore
         }
+        return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
     }
 
     private final void validateRect(Rect rect) {
@@ -843,7 +924,7 @@
         setStream(bitmapData, null, true);
     }
 
-    private void setWallpaper(InputStream data, FileOutputStream fos)
+    private void copyStreamToWallpaperFile(InputStream data, FileOutputStream fos)
             throws IOException {
         byte[] buffer = new byte[32768];
         int amt;
@@ -877,29 +958,55 @@
      * @throws IllegalArgumentException If the {@code visibleCropHint} rectangle is
      *     empty or invalid.
      */
-    public void setStream(InputStream bitmapData, Rect visibleCropHint, boolean allowBackup)
+    public int setStream(InputStream bitmapData, Rect visibleCropHint, boolean allowBackup)
             throws IOException {
+        return setStream(bitmapData, visibleCropHint, allowBackup, FLAG_SET_SYSTEM);
+    }
+
+    /**
+     * Version of {@link #setStream(InputStream, Rect, boolean)} that allows the caller
+     * to specify which of the supported wallpaper categories to set.
+     *
+     * @param bitmapData A stream containing the raw data to install as a wallpaper.
+     * @param visibleCropHint The rectangular subregion of the streamed image that should be
+     *     displayed as wallpaper.  Passing {@code null} for this parameter means that
+     *     the full image should be displayed if possible given the image's and device's
+     *     aspect ratios, etc.
+     * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
+     *     image for restore to a future device; {@code false} otherwise.
+     * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
+     *
+     * @see #FLAG_SET_LOCK_WALLPAPER
+     * @see #FLAG_SET_SYSTEM_WALLPAPER
+     *
+     * @throws IOException
+     */
+    public int setStream(InputStream bitmapData, Rect visibleCropHint,
+            boolean allowBackup, @SetWallpaperFlags int which)
+                    throws IOException {
         validateRect(visibleCropHint);
         if (sGlobals.mService == null) {
             Log.w(TAG, "WallpaperService not running");
-            return;
+            return 0;
         }
+        final Bundle result = new Bundle();
         try {
             ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,
-                    mContext.getOpPackageName());
-            if (fd == null) {
-                return;
-            }
-            FileOutputStream fos = null;
-            try {
-                fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
-                setWallpaper(bitmapData, fos);
-            } finally {
-                IoUtils.closeQuietly(fos);
+                    mContext.getOpPackageName(), result, which);
+            if (fd != null) {
+                FileOutputStream fos = null;
+                try {
+                    fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
+                    copyStreamToWallpaperFile(bitmapData, fos);
+                } finally {
+                    IoUtils.closeQuietly(fos);
+                }
             }
         } catch (RemoteException e) {
             // Ignore
         }
+
+        return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
     }
 
     /**
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index cfd5ca8..3c1ecc7 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -283,17 +283,17 @@
     public static final String EXTRA_BUGREPORT_FAILURE_REASON =
             "android.app.extra.BUGREPORT_FAILURE_REASON";
 
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        BUGREPORT_FAILURE_FAILED_COMPLETING,
-        BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
-    })
     /**
      * An interface representing reason of bugreport failure.
      *
      * @see #EXTRA_BUGREPORT_FAILURE_REASON
      * @hide
      */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        BUGREPORT_FAILURE_FAILED_COMPLETING,
+        BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
+    })
     public @interface BugreportFailureCode {}
     /** Bugreport completion process failed. */
     public static final int BUGREPORT_FAILURE_FAILED_COMPLETING = 0;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index a655bfd..768da6a 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -16,6 +16,7 @@
 
 package android.app.admin;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -53,6 +54,8 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
 import java.security.KeyFactory;
@@ -67,6 +70,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Public interface for managing policies enforced on a device. Most clients of this class must be
@@ -88,22 +92,25 @@
 
     private final Context mContext;
     private final IDevicePolicyManager mService;
-    private boolean mParentInstance;
+    private final boolean mParentInstance;
 
     private static final String REMOTE_EXCEPTION_MESSAGE =
             "Failed to talk with device policy manager service";
 
     private DevicePolicyManager(Context context, boolean parentInstance) {
-        this(context, IDevicePolicyManager.Stub.asInterface(
-                        ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)));
-        mParentInstance = parentInstance;
+        this(context,
+                IDevicePolicyManager.Stub.asInterface(
+                        ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)),
+                parentInstance);
     }
 
     /** @hide */
     @VisibleForTesting
-    protected DevicePolicyManager(Context context, IDevicePolicyManager service) {
+    protected DevicePolicyManager(
+            Context context, IDevicePolicyManager service, boolean parentInstance) {
         mContext = context;
         mService = service;
+        mParentInstance = parentInstance;
     }
 
     /** @hide */
@@ -276,6 +283,21 @@
         = "android.app.action.PROVISION_MANAGED_SHAREABLE_DEVICE";
 
     /**
+     * Activity action: Finalizes management provisioning, should be used after user-setup
+     * has been completed and {@link #getUserProvisioningState()} returns one of:
+     * <ul>
+     * <li>{@link #STATE_USER_SETUP_INCOMPLETE}</li>
+     * <li>{@link #STATE_USER_SETUP_COMPLETE}</li>
+     * <li>{@link #STATE_USER_PROFILE_COMPLETE}</li>
+     * </ul>
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_PROVISION_FINALIZATION
+            = "android.app.action.PROVISION_FINALIZATION";
+
+    /**
      * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
      * allows a mobile device management application or NFC programmer application which starts
      * managed provisioning to pass data to the management application instance after provisioning.
@@ -857,6 +879,44 @@
     public static final int PERMISSION_GRANT_STATE_DENIED = 2;
 
     /**
+     * No management for current user in-effect. This is the default.
+     * @hide
+     */
+    public static final int STATE_USER_UNMANAGED = 0;
+
+    /**
+     * Management partially setup, user setup needs to be completed.
+     * @hide
+     */
+    public static final int STATE_USER_SETUP_INCOMPLETE = 1;
+
+    /**
+     * Management partially setup, user setup completed.
+     * @hide
+     */
+    public static final int STATE_USER_SETUP_COMPLETE = 2;
+
+    /**
+     * Management setup and active on current user.
+     * @hide
+     */
+    public static final int STATE_USER_SETUP_FINALIZED = 3;
+
+    /**
+     * Management partially setup on a managed profile.
+     * @hide
+     */
+    public static final int STATE_USER_PROFILE_COMPLETE = 4;
+
+    /**
+     * @hide
+     */
+    @IntDef({STATE_USER_UNMANAGED, STATE_USER_SETUP_INCOMPLETE, STATE_USER_SETUP_COMPLETE,
+            STATE_USER_SETUP_FINALIZED, STATE_USER_PROFILE_COMPLETE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UserProvisioningState {}
+
+    /**
      * Return true if the given administrator component is currently
      * active (enabled) in the system.
      */
@@ -1145,7 +1205,7 @@
     public void setPasswordMinimumLength(@NonNull ComponentName admin, int length) {
         if (mService != null) {
             try {
-                mService.setPasswordMinimumLength(admin, length);
+                mService.setPasswordMinimumLength(admin, length, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1166,7 +1226,7 @@
     public int getPasswordMinimumLength(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getPasswordMinimumLength(admin, userHandle);
+                return mService.getPasswordMinimumLength(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1199,7 +1259,7 @@
     public void setPasswordMinimumUpperCase(@NonNull ComponentName admin, int length) {
         if (mService != null) {
             try {
-                mService.setPasswordMinimumUpperCase(admin, length);
+                mService.setPasswordMinimumUpperCase(admin, length, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1227,7 +1287,7 @@
     public int getPasswordMinimumUpperCase(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getPasswordMinimumUpperCase(admin, userHandle);
+                return mService.getPasswordMinimumUpperCase(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1260,7 +1320,7 @@
     public void setPasswordMinimumLowerCase(@NonNull ComponentName admin, int length) {
         if (mService != null) {
             try {
-                mService.setPasswordMinimumLowerCase(admin, length);
+                mService.setPasswordMinimumLowerCase(admin, length, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1288,7 +1348,7 @@
     public int getPasswordMinimumLowerCase(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getPasswordMinimumLowerCase(admin, userHandle);
+                return mService.getPasswordMinimumLowerCase(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1320,7 +1380,7 @@
     public void setPasswordMinimumLetters(@NonNull ComponentName admin, int length) {
         if (mService != null) {
             try {
-                mService.setPasswordMinimumLetters(admin, length);
+                mService.setPasswordMinimumLetters(admin, length, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1346,7 +1406,7 @@
     public int getPasswordMinimumLetters(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getPasswordMinimumLetters(admin, userHandle);
+                return mService.getPasswordMinimumLetters(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1378,7 +1438,7 @@
     public void setPasswordMinimumNumeric(@NonNull ComponentName admin, int length) {
         if (mService != null) {
             try {
-                mService.setPasswordMinimumNumeric(admin, length);
+                mService.setPasswordMinimumNumeric(admin, length, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1405,7 +1465,7 @@
     public int getPasswordMinimumNumeric(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getPasswordMinimumNumeric(admin, userHandle);
+                return mService.getPasswordMinimumNumeric(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1437,7 +1497,7 @@
     public void setPasswordMinimumSymbols(@NonNull ComponentName admin, int length) {
         if (mService != null) {
             try {
-                mService.setPasswordMinimumSymbols(admin, length);
+                mService.setPasswordMinimumSymbols(admin, length, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1463,7 +1523,7 @@
     public int getPasswordMinimumSymbols(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getPasswordMinimumSymbols(admin, userHandle);
+                return mService.getPasswordMinimumSymbols(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1495,7 +1555,7 @@
     public void setPasswordMinimumNonLetter(@NonNull ComponentName admin, int length) {
         if (mService != null) {
             try {
-                mService.setPasswordMinimumNonLetter(admin, length);
+                mService.setPasswordMinimumNonLetter(admin, length, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1522,7 +1582,7 @@
     public int getPasswordMinimumNonLetter(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getPasswordMinimumNonLetter(admin, userHandle);
+                return mService.getPasswordMinimumNonLetter(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1555,7 +1615,7 @@
     public void setPasswordHistoryLength(@NonNull ComponentName admin, int length) {
         if (mService != null) {
             try {
-                mService.setPasswordHistoryLength(admin, length);
+                mService.setPasswordHistoryLength(admin, length, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1587,7 +1647,7 @@
     public void setPasswordExpirationTimeout(@NonNull ComponentName admin, long timeout) {
         if (mService != null) {
             try {
-                mService.setPasswordExpirationTimeout(admin, timeout);
+                mService.setPasswordExpirationTimeout(admin, timeout, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1606,7 +1666,7 @@
     public long getPasswordExpirationTimeout(@Nullable ComponentName admin) {
         if (mService != null) {
             try {
-                return mService.getPasswordExpirationTimeout(admin, myUserId());
+                return mService.getPasswordExpirationTimeout(admin, myUserId(), mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1627,7 +1687,7 @@
     public long getPasswordExpiration(@Nullable ComponentName admin) {
         if (mService != null) {
             try {
-                return mService.getPasswordExpiration(admin, myUserId());
+                return mService.getPasswordExpiration(admin, myUserId(), mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1650,7 +1710,7 @@
     public int getPasswordHistoryLength(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getPasswordHistoryLength(admin, userHandle);
+                return mService.getPasswordHistoryLength(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1672,7 +1732,7 @@
     /**
      * Determine whether the current password the user has set is sufficient
      * to meet the policy requirements (quality, minimum length) that have been
-     * requested by the admins of this user and its profiles.
+     * requested by the admins of this user and its profiles that don't have a separate challenge.
      *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
@@ -1692,6 +1752,26 @@
     }
 
     /**
+     * Determine whether the current profile password the user has set is sufficient
+     * to meet the policy requirements (quality, minimum length) that have been
+     * requested by the admins of the parent user and its profiles.
+     *
+     * @param userHandle the userId of the profile to check the password for.
+     * @return Returns true if the password would meet the current requirements, else false.
+     * @hide
+     */
+    public boolean isProfileActivePasswordSufficientForParent(int userHandle) {
+        if (mService != null) {
+            try {
+                return mService.isProfileActivePasswordSufficientForParent(userHandle);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+        return false;
+    }
+
+    /**
      * Retrieve the number of times the user has failed at entering a
      * password since that last successful password entry.
      *
@@ -1702,7 +1782,7 @@
     public int getCurrentFailedPasswordAttempts() {
         if (mService != null) {
             try {
-                return mService.getCurrentFailedPasswordAttempts(myUserId());
+                return mService.getCurrentFailedPasswordAttempts(myUserId(), mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1749,7 +1829,7 @@
     public void setMaximumFailedPasswordsForWipe(@NonNull ComponentName admin, int num) {
         if (mService != null) {
             try {
-                mService.setMaximumFailedPasswordsForWipe(admin, num);
+                mService.setMaximumFailedPasswordsForWipe(admin, num, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1771,7 +1851,8 @@
     public int getMaximumFailedPasswordsForWipe(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getMaximumFailedPasswordsForWipe(admin, userHandle);
+                return mService.getMaximumFailedPasswordsForWipe(
+                        admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1789,7 +1870,8 @@
     public int getProfileWithMinimumFailedPasswordsForWipe(int userHandle) {
         if (mService != null) {
             try {
-                return mService.getProfileWithMinimumFailedPasswordsForWipe(userHandle);
+                return mService.getProfileWithMinimumFailedPasswordsForWipe(
+                        userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1881,7 +1963,7 @@
     public void setMaximumTimeToLock(@NonNull ComponentName admin, long timeMs) {
         if (mService != null) {
             try {
-                mService.setMaximumTimeToLock(admin, timeMs);
+                mService.setMaximumTimeToLock(admin, timeMs, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1904,7 +1986,7 @@
     public long getMaximumTimeToLock(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getMaximumTimeToLock(admin, userHandle);
+                return mService.getMaximumTimeToLock(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1923,7 +2005,7 @@
     public void lockNow() {
         if (mService != null) {
             try {
-                mService.lockNow();
+                mService.lockNow(mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -2688,6 +2770,45 @@
     }
 
     /**
+     * Called by a device owner to set whether all users created on the device should be ephemeral.
+     *
+     * <p>The system user is exempt from this policy - it is never ephemeral.
+     *
+     * <p>The calling device admin must be the device owner. If it is not, a security exception will
+     * be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param forceEphemeralUsers If true, all the existing users will be deleted and all
+     *         subsequently created users will be ephemeral.
+     * @hide
+     */
+    public void setForceEphemeralUsers(
+            @NonNull ComponentName admin, boolean forceEphemeralUsers) {
+        if (mService != null) {
+            try {
+                mService.setForceEphemeralUsers(admin, forceEphemeralUsers);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+    }
+
+    /**
+     * @return true if all users are created ephemeral.
+     * @hide
+     */
+    public boolean getForceEphemeralUsers(@NonNull ComponentName admin) {
+        if (mService != null) {
+            try {
+                return mService.getForceEphemeralUsers(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+        return false;
+    }
+
+    /**
      * Called by an application that is administering the device to disable keyguard customizations,
      * such as widgets. After setting this, keyguard features will be disabled according to the
      * provided feature list.
@@ -2720,7 +2841,7 @@
     public void setKeyguardDisabledFeatures(@NonNull ComponentName admin, int which) {
         if (mService != null) {
             try {
-                mService.setKeyguardDisabledFeatures(admin, which);
+                mService.setKeyguardDisabledFeatures(admin, which, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -2730,8 +2851,8 @@
     /**
      * Determine whether or not features have been disabled in keyguard either by the calling
      * admin, if specified, or all admins.
-     * @param admin The name of the admin component to check, or {@code null} to check whether any admins
-     * have disabled features in keyguard.
+     * @param admin The name of the admin component to check, or {@code null} to check whether any
+     * admins have disabled features in keyguard.
      * @return bitfield of flags. See {@link #setKeyguardDisabledFeatures(ComponentName, int)}
      * for a list.
      */
@@ -2743,7 +2864,7 @@
     public int getKeyguardDisabledFeatures(@Nullable ComponentName admin, int userHandle) {
         if (mService != null) {
             try {
-                return mService.getKeyguardDisabledFeatures(admin, userHandle);
+                return mService.getKeyguardDisabledFeatures(admin, userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -3730,14 +3851,15 @@
 
     /**
      * Start Quick Contact on the managed profile for the user, if the policy allows.
+     *
      * @hide
      */
     public void startManagedQuickContact(String actualLookupKey, long actualContactId,
-            long directoryId, Intent originalIntent) {
+            boolean isContactIdIgnored, long directoryId, Intent originalIntent) {
         if (mService != null) {
             try {
-                mService.startManagedQuickContact(
-                        actualLookupKey, actualContactId, directoryId, originalIntent);
+                mService.startManagedQuickContact(actualLookupKey, actualContactId,
+                        isContactIdIgnored, directoryId, originalIntent);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -3750,7 +3872,7 @@
      */
     public void startManagedQuickContact(String actualLookupKey, long actualContactId,
             Intent originalIntent) {
-        startManagedQuickContact(actualLookupKey, actualContactId, Directory.DEFAULT,
+        startManagedQuickContact(actualLookupKey, actualContactId, false, Directory.DEFAULT,
                 originalIntent);
     }
 
@@ -4119,6 +4241,57 @@
     }
 
     /**
+      * Flag used by {@link #createAndManageUser} to skip setup wizard after creating a new user.
+      */
+    public static final int SKIP_SETUP_WIZARD = 0x0001;
+
+    /**
+     * Flag used by {@link #createAndManageUser} to specify that the user should be created
+     * ephemeral.
+     * @hide
+     */
+    public static final int MAKE_USER_EPHEMERAL = 0x0002;
+
+    /**
+     * Called by a device owner to create a user with the specified name and a given component of
+     * the calling package as profile owner. The UserHandle returned by this method should not be
+     * persisted as user handles are recycled as users are removed and created. If you need to
+     * persist an identifier for this user, use {@link UserManager#getSerialNumberForUser}. The new
+     * user will not be started in the background.
+     *
+     * <p>admin is the {@link DeviceAdminReceiver} which is the device owner. profileOwner is also
+     * a DeviceAdminReceiver in the same package as admin, and will become the profile owner and
+     * will be registered as an active admin on the new user. The profile owner package will be
+     * installed on the new user.
+     *
+     * <p>If the adminExtras are not null, they will be stored on the device until the user is
+     * started for the first time. Then the extras will be passed to the admin when
+     * onEnable is called.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param name The user's name.
+     * @param profileOwner Which {@link DeviceAdminReceiver} will be profile owner. Has to be in the
+     *      same package as admin, otherwise no user is created and an IllegalArgumentException is
+     *      thrown.
+     * @param adminExtras Extras that will be passed to onEnable of the admin receiver on the new
+     *      user.
+     * @param flags {@link #SKIP_SETUP_WIZARD} is supported.
+     * @see UserHandle
+     * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
+     *         user could not be created.
+     */
+    public UserHandle createAndManageUser(@NonNull ComponentName admin, @NonNull String name,
+            @NonNull ComponentName profileOwner, @Nullable PersistableBundle adminExtras,
+            int flags) {
+        try {
+            return mService.createAndManageUser(admin, name, profileOwner, adminExtras, flags);
+        } catch (RemoteException re) {
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
+        }
+        return null;
+    }
+
+    /**
      * Called by a device owner to remove a user and all associated data. The primary user can
      * not be removed.
      *
@@ -4666,7 +4839,8 @@
      * @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
      * @see #getCrossProfileWidgetProviders(android.content.ComponentName)
      */
-    public boolean removeCrossProfileWidgetProvider(@NonNull ComponentName admin, String packageName) {
+    public boolean removeCrossProfileWidgetProvider(
+            @NonNull ComponentName admin, String packageName) {
         if (mService != null) {
             try {
                 return mService.removeCrossProfileWidgetProvider(admin, packageName);
@@ -5125,7 +5299,8 @@
     }
 
     /**
-     * Obtains a {@link DevicePolicyManager} whose calls act on the parent profile.
+     * Called by the profile owner of a managed profile to obtain a {@link DevicePolicyManager}
+     * whose calls act on the parent profile.
      *
      * <p> Note only some methods will work on the parent Manager.
      *
@@ -5193,4 +5368,80 @@
             return 0;
         }
     }
+
+    /**
+     * @return the {@link UserProvisioningState} for the current user - for unmanaged users will
+     *         return {@link #STATE_USER_UNMANAGED}
+     * @hide
+     */
+    @UserProvisioningState
+    public int getUserProvisioningState() {
+        if (mService != null) {
+            try {
+                return mService.getUserProvisioningState();
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+        return STATE_USER_UNMANAGED;
+    }
+
+    /**
+     * Set the {@link UserProvisioningState} for the supplied user, if they are managed.
+     *
+     * @param state to store
+     * @param userHandle for user
+     * @hide
+     */
+    public void setUserProvisioningState(@UserProvisioningState int state, int userHandle) {
+        if (mService != null) {
+            try {
+                mService.setUserProvisioningState(state, userHandle);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Indicates the entity that controls the device or profile owner. A user/profile is considered
+     * affiliated if it is managed by the same entity as the device.
+     *
+     * <p> By definition, the user that the device owner runs on is always affiliated. Any other
+     * user/profile is considered affiliated if the following conditions are both met:
+     * <ul>
+     * <li>The device owner and the user's/profile's profile owner have called this method,
+     *   specifying a set of opaque affiliation ids each. If the sets specified by the device owner
+     *   and a profile owner intersect, they must have come from the same source, which means that
+     *   the device owner and profile owner are controlled by the same entity.</li>
+     * <li>The device owner's and profile owner's package names are the same.</li>
+     * </ul>
+     *
+     * @param admin Which profile or device owner this request is associated with.
+     * @param ids A set of opaque affiliation ids.
+     */
+    public void setAffiliationIds(@NonNull ComponentName admin, Set<String> ids) {
+        try {
+            mService.setAffiliationIds(admin, new ArrayList<String>(ids));
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed talking with device policy service", e);
+        }
+    }
+
+    /**
+     * @hide
+     * Returns whether this user/profile is affiliated with the device. See
+     * {@link #setAffiliationIds} for the definition of affiliation.
+     *
+     * @return whether this user/profile is affiliated with the device.
+     */
+    public boolean isAffiliatedUser() {
+        try {
+            return mService != null && mService.isAffiliatedUser();
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed talking with device policy service", e);
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 82115a2..20d4a29 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -38,48 +38,49 @@
     void setPasswordQuality(in ComponentName who, int quality, boolean parent);
     int getPasswordQuality(in ComponentName who, int userHandle, boolean parent);
 
-    void setPasswordMinimumLength(in ComponentName who, int length);
-    int getPasswordMinimumLength(in ComponentName who, int userHandle);
+    void setPasswordMinimumLength(in ComponentName who, int length, boolean parent);
+    int getPasswordMinimumLength(in ComponentName who, int userHandle, boolean parent);
 
-    void setPasswordMinimumUpperCase(in ComponentName who, int length);
-    int getPasswordMinimumUpperCase(in ComponentName who, int userHandle);
+    void setPasswordMinimumUpperCase(in ComponentName who, int length, boolean parent);
+    int getPasswordMinimumUpperCase(in ComponentName who, int userHandle, boolean parent);
 
-    void setPasswordMinimumLowerCase(in ComponentName who, int length);
-    int getPasswordMinimumLowerCase(in ComponentName who, int userHandle);
+    void setPasswordMinimumLowerCase(in ComponentName who, int length, boolean parent);
+    int getPasswordMinimumLowerCase(in ComponentName who, int userHandle, boolean parent);
 
-    void setPasswordMinimumLetters(in ComponentName who, int length);
-    int getPasswordMinimumLetters(in ComponentName who, int userHandle);
+    void setPasswordMinimumLetters(in ComponentName who, int length, boolean parent);
+    int getPasswordMinimumLetters(in ComponentName who, int userHandle, boolean parent);
 
-    void setPasswordMinimumNumeric(in ComponentName who, int length);
-    int getPasswordMinimumNumeric(in ComponentName who, int userHandle);
+    void setPasswordMinimumNumeric(in ComponentName who, int length, boolean parent);
+    int getPasswordMinimumNumeric(in ComponentName who, int userHandle, boolean parent);
 
-    void setPasswordMinimumSymbols(in ComponentName who, int length);
-    int getPasswordMinimumSymbols(in ComponentName who, int userHandle);
+    void setPasswordMinimumSymbols(in ComponentName who, int length, boolean parent);
+    int getPasswordMinimumSymbols(in ComponentName who, int userHandle, boolean parent);
 
-    void setPasswordMinimumNonLetter(in ComponentName who, int length);
-    int getPasswordMinimumNonLetter(in ComponentName who, int userHandle);
+    void setPasswordMinimumNonLetter(in ComponentName who, int length, boolean parent);
+    int getPasswordMinimumNonLetter(in ComponentName who, int userHandle, boolean parent);
 
-    void setPasswordHistoryLength(in ComponentName who, int length);
-    int getPasswordHistoryLength(in ComponentName who, int userHandle);
+    void setPasswordHistoryLength(in ComponentName who, int length, boolean parent);
+    int getPasswordHistoryLength(in ComponentName who, int userHandle, boolean parent);
 
-    void setPasswordExpirationTimeout(in ComponentName who, long expiration);
-    long getPasswordExpirationTimeout(in ComponentName who, int userHandle);
+    void setPasswordExpirationTimeout(in ComponentName who, long expiration, boolean parent);
+    long getPasswordExpirationTimeout(in ComponentName who, int userHandle, boolean parent);
 
-    long getPasswordExpiration(in ComponentName who, int userHandle);
+    long getPasswordExpiration(in ComponentName who, int userHandle, boolean parent);
 
     boolean isActivePasswordSufficient(int userHandle, boolean parent);
-    int getCurrentFailedPasswordAttempts(int userHandle);
-    int getProfileWithMinimumFailedPasswordsForWipe(int userHandle);
+    boolean isProfileActivePasswordSufficientForParent(int userHandle);
+    int getCurrentFailedPasswordAttempts(int userHandle, boolean parent);
+    int getProfileWithMinimumFailedPasswordsForWipe(int userHandle, boolean parent);
 
-    void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num);
-    int getMaximumFailedPasswordsForWipe(in ComponentName admin, int userHandle);
+    void setMaximumFailedPasswordsForWipe(in ComponentName admin, int num, boolean parent);
+    int getMaximumFailedPasswordsForWipe(in ComponentName admin, int userHandle, boolean parent);
 
     boolean resetPassword(String password, int flags);
 
-    void setMaximumTimeToLock(in ComponentName who, long timeMs);
-    long getMaximumTimeToLock(in ComponentName who, int userHandle);
+    void setMaximumTimeToLock(in ComponentName who, long timeMs, boolean parent);
+    long getMaximumTimeToLock(in ComponentName who, int userHandle, boolean parent);
 
-    void lockNow();
+    void lockNow(boolean parent);
 
     void wipeData(int flags);
 
@@ -99,8 +100,8 @@
     void setScreenCaptureDisabled(in ComponentName who, boolean disabled);
     boolean getScreenCaptureDisabled(in ComponentName who, int userHandle);
 
-    void setKeyguardDisabledFeatures(in ComponentName who, int which);
-    int getKeyguardDisabledFeatures(in ComponentName who, int userHandle);
+    void setKeyguardDisabledFeatures(in ComponentName who, int which, boolean parent);
+    int getKeyguardDisabledFeatures(in ComponentName who, int userHandle, boolean parent);
 
     void setActiveAdmin(in ComponentName policyReceiver, boolean refreshing, int userHandle);
     boolean isAdminActive(in ComponentName policyReceiver, int userHandle);
@@ -179,6 +180,7 @@
 
     UserHandle createUser(in ComponentName who, in String name);
     UserHandle createAndInitializeUser(in ComponentName who, in String name, in String profileOwnerName, in ComponentName profileOwnerComponent, in Bundle adminExtras);
+    UserHandle createAndManageUser(in ComponentName who, in String name, in ComponentName profileOwner, in PersistableBundle adminExtras, in int flags);
     boolean removeUser(in ComponentName who, in UserHandle userHandle);
     boolean switchUser(in ComponentName who, in UserHandle userHandle);
 
@@ -210,7 +212,7 @@
     void setCrossProfileContactsSearchDisabled(in ComponentName who, boolean disabled);
     boolean getCrossProfileContactsSearchDisabled(in ComponentName who);
     boolean getCrossProfileContactsSearchDisabledForUser(int userId);
-    void startManagedQuickContact(String lookupKey, long contactId, long directoryId, in Intent originalIntent);
+    void startManagedQuickContact(String lookupKey, long contactId, boolean isContactIdIgnored, long directoryId, in Intent originalIntent);
 
     void setBluetoothContactSharingDisabled(in ComponentName who, boolean disabled);
     boolean getBluetoothContactSharingDisabled(in ComponentName who);
@@ -228,6 +230,9 @@
     void setAutoTimeRequired(in ComponentName who, boolean required);
     boolean getAutoTimeRequired();
 
+    void setForceEphemeralUsers(in ComponentName who, boolean forceEpehemeralUsers);
+    boolean getForceEphemeralUsers(in ComponentName who);
+
     boolean isRemovingAdmin(in ComponentName adminReceiver, int userHandle);
 
     void setUserIcon(in ComponentName admin, in Bitmap icon);
@@ -267,4 +272,10 @@
     void setOrganizationColor(in ComponentName admin, in int color);
     int getOrganizationColor(in ComponentName admin);
     int getOrganizationColorForUser(int userHandle);
+
+    int getUserProvisioningState();
+    void setUserProvisioningState(int state, int userHandle);
+
+    void setAffiliationIds(in ComponentName admin, in List<String> ids);
+    boolean isAffiliatedUser();
 }
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index aa4a631..63f1425 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -382,6 +382,28 @@
     }
 
     /**
+     * Tells the application agent that the backup data size exceeded current transport quota.
+     * Later calls to {@link #onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)}
+     * and {@link #onFullBackup(FullBackupDataOutput)} could use this information
+     * to reduce backup size under the limit.
+     * However, the quota can change, so do not assume that the value passed in here is absolute,
+     * similarly all subsequent backups should not be restricted to this size.
+     * This callback will be invoked before data has been put onto the wire in a preflight check,
+     * so it is relatively inexpensive to hit your quota.
+     * Apps that hit quota repeatedly without dealing with it can be subject to having their backup
+     * schedule reduced.
+     * The {@code quotaBytes} is a loose guideline b/c of metadata added by the backupmanager
+     * so apps should be more aggressive in trimming their backup set.
+     *
+     * @param backupDataBytes Expected or already processed amount of data.
+     *                        Could be less than total backup size if backup process was interrupted
+     *                        before finish of processing all backup data.
+     * @param quotaBytes Current amount of backup data that is allowed for the app.
+     */
+    public void onQuotaExceeded(long backupDataBytes, long quotaBytes) {
+    }
+
+    /**
      * Check whether the xml yielded any <include/> tag for the provided <code>domainToken</code>.
      * If so, perform a {@link #fullBackupFileTree} which backs up the file or recurses if the path
      * is a directory.
@@ -955,6 +977,21 @@
         public void fail(String message) {
             getHandler().post(new FailRunnable(message));
         }
+
+        @Override
+        public void doQuotaExceeded(long backupDataBytes, long quotaBytes) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                BackupAgent.this.onQuotaExceeded(backupDataBytes, quotaBytes);
+            } catch (Exception e) {
+                Log.d(TAG, "onQuotaExceeded(" + BackupAgent.this.getClass().getName() + ") threw",
+                        e);
+                throw e;
+            } finally {
+                waitForSharedPrefs();
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
     }
 
     static class FailRunnable implements Runnable {
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index c27eaa4f..ff62b7c 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -110,6 +110,16 @@
             BackupTransport.TRANSPORT_PACKAGE_REJECTED;
 
     /**
+     * Returned when the transport reject the attempt to backup because
+     * backup data size exceeded current quota limit for this package.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int ERROR_TRANSPORT_QUOTA_EXCEEDED =
+            BackupTransport.TRANSPORT_QUOTA_EXCEEDED;
+
+    /**
      * The {@link BackupAgent} for the requested package failed for some reason
      * and didn't provide appropriate backup data.
      *
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index aca115f..ac23b68 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -49,6 +49,7 @@
     public static final int TRANSPORT_PACKAGE_REJECTED = -1002;
     public static final int AGENT_ERROR = -1003;
     public static final int AGENT_UNKNOWN = -1004;
+    public static final int TRANSPORT_QUOTA_EXCEEDED = -1005;
 
     // Indicates that operation was initiated by user, not a scheduled one.
     // Transport should ignore its own moratoriums for call with this flag set.
@@ -494,6 +495,18 @@
         return true;
     }
 
+    /**
+     * Ask the transport about current quota for backup size of the package.
+     *
+     * @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.
+     */
+    public long getBackupQuota(String packageName, boolean isFullBackup) {
+        return Long.MAX_VALUE;
+    }
+
     // ------------------------------------------------------------------------------------
     // Full restore interfaces
 
@@ -677,6 +690,11 @@
         }
 
         @Override
+        public long getBackupQuota(String packageName, boolean isFullBackup) {
+            return BackupTransport.this.getBackupQuota(packageName, isFullBackup);
+        }
+
+        @Override
         public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
             return BackupTransport.this.getNextFullRestoreDataChunk(socket);
         }
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 9ad35d4..0143797 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -16,11 +16,16 @@
 
 package android.app.job;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ComponentName;
+import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import java.util.ArrayList;
+
 /**
  * Container of data passed to the {@link android.app.job.JobScheduler} fully encapsulating the
  * parameters required to schedule work against the calling application. These are constructed
@@ -80,6 +85,7 @@
     private final ComponentName service;
     private final boolean requireCharging;
     private final boolean requireDeviceIdle;
+    private final TriggerContentUri[] triggerContentUris;
     private final boolean hasEarlyConstraint;
     private final boolean hasLateConstraint;
     private final int networkType;
@@ -134,6 +140,15 @@
     }
 
     /**
+     * Which content: URIs must change for the job to be scheduled.  Returns null
+     * if there are none required.
+     */
+    @Nullable
+    public TriggerContentUri[] getTriggerContentUris() {
+        return triggerContentUris;
+    }
+
+    /**
      * One of {@link android.app.job.JobInfo#NETWORK_TYPE_ANY},
      * {@link android.app.job.JobInfo#NETWORK_TYPE_NONE}, or
      * {@link android.app.job.JobInfo#NETWORK_TYPE_UNMETERED}.
@@ -232,6 +247,7 @@
         service = in.readParcelable(null);
         requireCharging = in.readInt() == 1;
         requireDeviceIdle = in.readInt() == 1;
+        triggerContentUris = in.createTypedArray(TriggerContentUri.CREATOR);
         networkType = in.readInt();
         minLatencyMillis = in.readLong();
         maxExecutionDelayMillis = in.readLong();
@@ -252,6 +268,9 @@
         service = b.mJobService;
         requireCharging = b.mRequiresCharging;
         requireDeviceIdle = b.mRequiresDeviceIdle;
+        triggerContentUris = b.mTriggerContentUris != null
+                ? b.mTriggerContentUris.toArray(new TriggerContentUri[b.mTriggerContentUris.size()])
+                : null;
         networkType = b.mNetworkType;
         minLatencyMillis = b.mMinLatencyMillis;
         maxExecutionDelayMillis = b.mMaxExecutionDelayMillis;
@@ -278,6 +297,7 @@
         out.writeParcelable(service, flags);
         out.writeInt(requireCharging ? 1 : 0);
         out.writeInt(requireDeviceIdle ? 1 : 0);
+        out.writeTypedArray(triggerContentUris, flags);
         out.writeInt(networkType);
         out.writeLong(minLatencyMillis);
         out.writeLong(maxExecutionDelayMillis);
@@ -309,6 +329,75 @@
         return "(job:" + jobId + "/" + service.flattenToShortString() + ")";
     }
 
+    /**
+     * Information about a content URI modification that a job would like to
+     * trigger on.
+     */
+    public static final class TriggerContentUri implements Parcelable {
+        private final Uri mUri;
+        private final int mFlags;
+
+        /**
+         * Flag for trigger: also trigger if any descendants of the given URI change.
+         * Corresponds to the <var>notifyForDescendants</var> of
+         * {@link android.content.ContentResolver#registerContentObserver}.
+         */
+        public static final int FLAG_NOTIFY_FOR_DESCENDANTS = 1<<0;
+
+        /**
+         * Create a new trigger description.
+         * @param uri The URI to observe.  Must be non-null.
+         * @param flags Optional flags for the observer, either 0 or
+         * {@link #FLAG_NOTIFY_FOR_DESCENDANTS}.
+         */
+        public TriggerContentUri(@NonNull Uri uri, int flags) {
+            mUri = uri;
+            mFlags = flags;
+        }
+
+        /**
+         * Return the Uri this trigger was created for.
+         */
+        public Uri getUri() {
+            return mUri;
+        }
+
+        /**
+         * Return the flags supplied for the trigger.
+         */
+        public int getFlags() {
+            return mFlags;
+        }
+
+        private TriggerContentUri(Parcel in) {
+            mUri = Uri.CREATOR.createFromParcel(in);
+            mFlags = in.readInt();
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            mUri.writeToParcel(out, flags);
+            out.writeInt(mFlags);
+        }
+
+        public static final Creator<TriggerContentUri> CREATOR = new Creator<TriggerContentUri>() {
+            @Override
+            public TriggerContentUri createFromParcel(Parcel in) {
+                return new TriggerContentUri(in);
+            }
+
+            @Override
+            public TriggerContentUri[] newArray(int size) {
+                return new TriggerContentUri[size];
+            }
+        };
+    }
+
     /** Builder class for constructing {@link JobInfo} objects. */
     public static final class Builder {
         private int mJobId;
@@ -319,6 +408,7 @@
         private boolean mRequiresCharging;
         private boolean mRequiresDeviceIdle;
         private int mNetworkType;
+        private ArrayList<TriggerContentUri> mTriggerContentUris;
         private boolean mIsPersisted;
         // One-off parameters.
         private long mMinLatencyMillis;
@@ -403,6 +493,25 @@
         }
 
         /**
+         * Add a new content: URI that will be monitored with a
+         * {@link android.database.ContentObserver}, and will cause the job to execute if changed.
+         * If you have any trigger content URIs associated with a job, it will not execute until
+         * there has been a change report for one or more of them.
+         * <p>Note that trigger URIs can not be used in combination with
+         * {@link #setPeriodic(long)} or {@link #setPersisted(boolean)}.  To continually monitor
+         * for content changes, you need to schedule a new JobInfo observing the same URIs
+         * before you finish execution of the JobService handling the most recent changes.</p>
+         * @param uri The content: URI to monitor.
+         */
+        public Builder addTriggerContentUri(@NonNull TriggerContentUri uri) {
+            if (mTriggerContentUris == null) {
+                mTriggerContentUris = new ArrayList<>();
+            }
+            mTriggerContentUris.add(uri);
+            return this;
+        }
+
+        /**
          * Specify that this job should recur with the provided interval, not more than once per
          * period. You have no control over when within this interval this job will be executed,
          * only the guarantee that it will be executed at most once within this interval.
@@ -498,7 +607,8 @@
         public JobInfo build() {
             // Allow jobs with no constraints - What am I, a database?
             if (!mHasEarlyConstraint && !mHasLateConstraint && !mRequiresCharging &&
-                    !mRequiresDeviceIdle && mNetworkType == NETWORK_TYPE_NONE) {
+                    !mRequiresDeviceIdle && mNetworkType == NETWORK_TYPE_NONE &&
+                    mTriggerContentUris == null) {
                 throw new IllegalArgumentException("You're trying to build a job with no " +
                         "constraints, this is not allowed.");
             }
@@ -512,6 +622,14 @@
                 throw new IllegalArgumentException("Can't call setMinimumLatency() on a " +
                         "periodic job");
             }
+            if (mIsPeriodic && (mTriggerContentUris != null)) {
+                throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " +
+                        "periodic job");
+            }
+            if (mIsPersisted && (mTriggerContentUris != null)) {
+                throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " +
+                        "persisted job");
+            }
             if (mBackoffPolicySet && mRequiresDeviceIdle) {
                 throw new IllegalArgumentException("An idle mode job will not respect any" +
                         " back-off policy, so calling setBackoffCriteria with" +
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
index a0a60e8..8b309e11 100644
--- a/core/java/android/app/job/JobParameters.java
+++ b/core/java/android/app/job/JobParameters.java
@@ -17,6 +17,7 @@
 package android.app.job;
 
 import android.app.job.IJobCallback;
+import android.net.Uri;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -43,15 +44,21 @@
     private final PersistableBundle extras;
     private final IBinder callback;
     private final boolean overrideDeadlineExpired;
+    private final Uri[] mTriggeredContentUris;
+    private final String[] mTriggeredContentAuthorities;
+
     private int stopReason; // Default value of stopReason is REASON_CANCELED
 
     /** @hide */
     public JobParameters(IBinder callback, int jobId, PersistableBundle extras,
-                         boolean overrideDeadlineExpired) {
+                boolean overrideDeadlineExpired, Uri[] triggeredContentUris,
+            String[] triggeredContentAuthorities) {
         this.jobId = jobId;
         this.extras = extras;
         this.callback = callback;
         this.overrideDeadlineExpired = overrideDeadlineExpired;
+        this.mTriggeredContentUris = triggeredContentUris;
+        this.mTriggeredContentAuthorities = triggeredContentAuthorities;
     }
 
     /**
@@ -88,6 +95,30 @@
         return overrideDeadlineExpired;
     }
 
+    /**
+     * For jobs with {@link android.app.job.JobInfo.Builder#addTriggerContentUri} set, this
+     * reports which URIs have triggered the job.  This will be null if either no URIs have
+     * triggered it (it went off due to a deadline or other reason), or the number of changed
+     * URIs is too large to report.  Whether or not the number of URIs is too large, you can
+     * always use {@link #getTriggeredContentAuthorities()} to determine whether the job was
+     * triggered due to any content changes and the authorities they are associated with.
+     */
+    public Uri[] getTriggeredContentUris() {
+        return mTriggeredContentUris;
+    }
+
+    /**
+     * For jobs with {@link android.app.job.JobInfo.Builder#addTriggerContentUri} set, this
+     * reports which content authorities have triggered the job.  It will only be null if no
+     * authorities have triggered it -- that is, the job executed for some other reason, such
+     * as a deadline expiring.  If this is non-null, you can use {@link #getTriggeredContentUris()}
+     * to retrieve the details of which URIs changed (as long as that has not exceeded the maximum
+     * number it can reported).
+     */
+    public String[] getTriggeredContentAuthorities() {
+        return mTriggeredContentAuthorities;
+    }
+
     /** @hide */
     public IJobCallback getCallback() {
         return IJobCallback.Stub.asInterface(callback);
@@ -98,6 +129,8 @@
         extras = in.readPersistableBundle();
         callback = in.readStrongBinder();
         overrideDeadlineExpired = in.readInt() == 1;
+        mTriggeredContentUris = in.createTypedArray(Uri.CREATOR);
+        mTriggeredContentAuthorities = in.createStringArray();
         stopReason = in.readInt();
     }
 
@@ -117,6 +150,8 @@
         dest.writePersistableBundle(extras);
         dest.writeStrongBinder(callback);
         dest.writeInt(overrideDeadlineExpired ? 1 : 0);
+        dest.writeTypedArray(mTriggeredContentUris, flags);
+        dest.writeStringArray(mTriggeredContentAuthorities);
         dest.writeInt(stopReason);
     }
 
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index a3fe6ab..d3d02e5 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -32,4 +32,5 @@
     void setDeviceLockedForUser(int userId, boolean locked);
     boolean isDeviceLocked(int userId);
     boolean isDeviceSecure(int userId);
+    boolean isTrustUsuallyManaged(int userId);
 }
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 88ba874..999d826 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -16,21 +16,17 @@
 
 package android.app.trust;
 
+import com.android.internal.widget.LockPatternUtils;
+
 import android.Manifest;
-import android.annotation.IntDef;
 import android.annotation.RequiresPermission;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.SparseIntArray;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 
 /**
  * See {@link com.android.server.trust.TrustManagerService}
@@ -158,6 +154,21 @@
         }
     }
 
+    /**
+     * @return whether {@param userId} has enabled and configured trust agents. Ignores short-term
+     * unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}.
+     */
+    @RequiresPermission(android.Manifest.permission.TRUST_LISTENER)
+    public boolean isTrustUsuallyManaged(int userId) {
+        try {
+            return mService.isTrustUsuallyManaged(userId);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+
+
     private void onError(Exception e) {
         Log.e(TAG, "Error while calling TrustManagerService", e);
     }
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index 498ff81..b6f1567 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -19,6 +19,8 @@
 import android.content.ComponentName;
 import android.content.res.Configuration;
 
+import java.io.IOException;
+
 /**
  * UsageStatsManager local system service interface.
  *
@@ -109,4 +111,9 @@
         public abstract void onParoleStateChanged(boolean isParoleOn);
     }
 
+    /*  Backup/Restore API */
+    public abstract byte[] getBackupPayload(int user, String key);
+
+    public abstract void applyRestoredPayload(int user, String key, byte[] payload);
+
 }
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 74cb0f6..9cd7d05 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -104,8 +104,6 @@
     void getActivityEnergyInfoFromController();
     BluetoothActivityEnergyInfo reportActivityInfo();
 
-    // For dumpsys support
-    void dump(in ParcelFileDescriptor fd);
     void onLeServiceUp();
     void onBrEdrDown();
 }
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 3660be7..6b5f77f 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -23,6 +23,7 @@
 import android.bluetooth.le.ScanSettings;
 import android.bluetooth.le.ResultStorageDescriptor;
 import android.os.ParcelUuid;
+import android.os.WorkSource;
 
 import android.bluetooth.IBluetoothGattCallback;
 import android.bluetooth.IBluetoothGattServerCallback;
@@ -35,8 +36,8 @@
     List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
 
     void startScan(in int appIf, in boolean isServer, in ScanSettings settings,
-                   in List<ScanFilter> filters,
-                   in List scanStorages, in String callingPackage);
+                   in List<ScanFilter> filters, in WorkSource workSource, in List scanStorages,
+                   in String callingPackage);
     void stopScan(in int appIf, in boolean isServer);
     void flushPendingBatchResults(in int appIf, in boolean isServer);
     void startMultiAdvertising(in int appIf,
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 2ba87744..03449cc 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -29,6 +29,7 @@
 import android.os.Looper;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
+import android.os.WorkSource;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -89,9 +90,6 @@
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public void startScan(final ScanCallback callback) {
-        if (callback == null) {
-            throw new IllegalArgumentException("callback is null");
-        }
         startScan(null, new ScanSettings.Builder().build(), callback);
     }
 
@@ -112,14 +110,53 @@
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public void startScan(List<ScanFilter> filters, ScanSettings settings,
             final ScanCallback callback) {
-        startScan(filters, settings, callback, null);
+        startScan(filters, settings, null, callback, null);
+    }
+
+    /**
+     * Start Bluetooth LE scan. Same as {@link #startScan(ScanCallback)} but allows the caller to
+     * specify on behalf of which application(s) the work is being done.
+     *
+     * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
+     *                   the scan.
+     * @param callback Callback used to deliver scan results.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {
+            Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
+    public void startScanFromSource(final WorkSource workSource, final ScanCallback callback) {
+        startScanFromSource(null, new ScanSettings.Builder().build(), workSource, callback);
+    }
+
+    /**
+     * Start Bluetooth LE scan. Same as {@link #startScan(List, ScanSettings, ScanCallback)} but
+     * allows the caller to specify on behalf of which application(s) the work is being done.
+     *
+     * @param filters {@link ScanFilter}s for finding exact BLE devices.
+     * @param settings Settings for the scan.
+     * @param workSource {@link WorkSource} identifying the application(s) for which to blame for
+     *                   the scan.
+     * @param callback Callback used to deliver scan results.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {
+            Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
+    public void startScanFromSource(List<ScanFilter> filters, ScanSettings settings,
+                                    final WorkSource workSource, final ScanCallback callback) {
+        startScan(filters, settings, workSource, callback, null);
     }
 
     private void startScan(List<ScanFilter> filters, ScanSettings settings,
-            final ScanCallback callback, List<List<ResultStorageDescriptor>> resultStorages) {
+                           final WorkSource workSource, final ScanCallback callback,
+                           List<List<ResultStorageDescriptor>> resultStorages) {
         BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-        if (settings == null || callback == null) {
-            throw new IllegalArgumentException("settings or callback is null");
+        if (callback == null) {
+            throw new IllegalArgumentException("callback is null");
+        }
+        if (settings == null) {
+            throw new IllegalArgumentException("settings is null");
         }
         synchronized (mLeScanClients) {
             if (mLeScanClients.containsKey(callback)) {
@@ -152,7 +189,7 @@
                 return;
             }
             BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
-                    settings, callback, resultStorages);
+                    settings, workSource, callback, resultStorages);
             wrapper.startRegisteration();
         }
     }
@@ -215,7 +252,7 @@
             scanFilters.add(filter.getFilter());
             scanStorages.add(filter.getStorageDescriptors());
         }
-        startScan(scanFilters, settings, callback, scanStorages);
+        startScan(scanFilters, settings, null, callback, scanStorages);
     }
 
     /**
@@ -235,6 +272,7 @@
 
         private final ScanCallback mScanCallback;
         private final List<ScanFilter> mFilters;
+        private final WorkSource mWorkSource;
         private ScanSettings mSettings;
         private IBluetoothGatt mBluetoothGatt;
         private List<List<ResultStorageDescriptor>> mResultStorages;
@@ -246,10 +284,12 @@
 
         public BleScanCallbackWrapper(IBluetoothGatt bluetoothGatt,
                 List<ScanFilter> filters, ScanSettings settings,
-                ScanCallback scanCallback, List<List<ResultStorageDescriptor>> resultStorages) {
+                WorkSource workSource, ScanCallback scanCallback,
+                List<List<ResultStorageDescriptor>> resultStorages) {
             mBluetoothGatt = bluetoothGatt;
             mFilters = filters;
             mSettings = settings;
+            mWorkSource = workSource;
             mScanCallback = scanCallback;
             mClientIf = 0;
             mResultStorages = resultStorages;
@@ -322,7 +362,9 @@
                     mClientIf = clientIf;
                     try {
                         mBluetoothGatt.startScan(mClientIf, false, mSettings, mFilters,
-                                mResultStorages, ActivityThread.currentOpPackageName());
+                                mWorkSource, mResultStorages,
+                                ActivityThread.currentOpPackageName());
+
                     } catch (RemoteException e) {
                         Log.e(TAG, "fail to start le scan: " + e);
                         mClientIf = -1;
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 0b80f8a..6dfefac 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -17,11 +17,14 @@
 package android.content;
 
 import static android.content.ContentProvider.maybeAddUserId;
+
+import android.content.pm.PackageManager;
 import android.content.res.AssetFileDescriptor;
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Process;
 import android.os.StrictMode;
 import android.text.Html;
 import android.text.Spannable;
@@ -462,7 +465,12 @@
                 // Check to see what data representations the content
                 // provider supports.  We would like HTML text, but if that
                 // is not possible we'll live with plan text.
-                String[] types = context.getContentResolver().getStreamTypes(mUri, "text/*");
+                String[] types = null;
+                try {
+                    types = context.getContentResolver().getStreamTypes(mUri, "text/*");
+                } catch (SecurityException e) {
+                    // No read permission for mUri, assume empty stream types list.
+                }
                 boolean hasHtml = false;
                 boolean hasText = false;
                 if (types != null) {
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 684a85e..3461c11 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1592,20 +1592,20 @@
      *
      * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI
      * for a whole class of content.
-     * @param notifyForDescendents When false, the observer will be notified whenever a
+     * @param notifyForDescendants When false, the observer will be notified whenever a
      * change occurs to the exact URI specified by <code>uri</code> or to one of the
      * URI's ancestors in the path hierarchy.  When true, the observer will also be notified
      * whenever a change occurs to the URI's descendants in the path hierarchy.
      * @param observer The object that receives callbacks when changes occur.
      * @see #unregisterContentObserver
      */
-    public final void registerContentObserver(@NonNull Uri uri, boolean notifyForDescendents,
+    public final void registerContentObserver(@NonNull Uri uri, boolean notifyForDescendants,
             @NonNull ContentObserver observer) {
         Preconditions.checkNotNull(uri, "uri");
         Preconditions.checkNotNull(observer, "observer");
         registerContentObserver(
                 ContentProvider.getUriWithoutUserId(uri),
-                notifyForDescendents,
+                notifyForDescendants,
                 observer,
                 ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
     }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 48d0196..3142b40 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -48,6 +48,7 @@
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
+import android.os.HardwarePropertiesManager;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.StatFs;
@@ -2561,7 +2562,6 @@
             //@hide: NETWORK_POLICY_SERVICE,
             WIFI_SERVICE,
             WIFI_NAN_SERVICE,
-            WIFI_PASSPOINT_SERVICE,
             WIFI_P2P_SERVICE,
             WIFI_SCANNING_SERVICE,
             //@hide: WIFI_RTT_SERVICE,
@@ -2612,6 +2612,8 @@
             MEDIA_PROJECTION_SERVICE,
             MIDI_SERVICE,
             RADIO_SERVICE,
+            HARDWARE_PROPERTIES_SERVICE,
+            //@hide: SOUND_TRIGGER_SERVICE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ServiceName {}
@@ -2673,6 +2675,8 @@
      * <dt> {@link #NETWORK_STATS_SERVICE} ("netstats")
      * <dd> A {@link android.app.usage.NetworkStatsManager NetworkStatsManager} for querying network
      * usage statistics.
+     * <dt> {@link #HARDWARE_PROPERTIES_SERVICE} ("hardwareproperties")
+     * <dd> A {@link android.os.HardwarePropertiesManager} for accessing hardware properties.
      * </dl>
      *
      * <p>Note:  System services obtained via this API may be closely associated with
@@ -2734,6 +2738,8 @@
      * @see android.app.job.JobScheduler
      * @see #NETWORK_STATS_SERVICE
      * @see android.app.usage.NetworkStatsManager
+     * @see android.os.HardwarePropertiesManager
+     * @see #HARDWARE_PROPERTIES_SERVICE
      */
     public abstract Object getSystemService(@ServiceName @NonNull String name);
 
@@ -3003,17 +3009,6 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
-     * android.net.wifi.passpoint.WifiPasspointManager} for handling management of
-     * Wi-Fi passpoint access.
-     *
-     * @see #getSystemService
-     * @see android.net.wifi.passpoint.WifiPasspointManager
-     * @hide
-     */
-    public static final String WIFI_PASSPOINT_SERVICE = "wifipasspoint";
-
-    /**
-     * Use with {@link #getSystemService} to retrieve a {@link
      * android.net.wifi.p2p.WifiP2pManager} for handling management of
      * Wi-Fi peer-to-peer connections.
      *
@@ -3201,6 +3196,16 @@
     public static final String VOICE_INTERACTION_MANAGER_SERVICE = "voiceinteraction";
 
     /**
+     * Use with {@link #getSystemService} to access the
+     * {@link com.android.server.voiceinteraction.SoundTriggerService}.
+     *
+     * @hide
+     * @see #getSystemService
+     */
+    public static final String SOUND_TRIGGER_SERVICE = "soundtrigger";
+
+
+    /**
      * Use with {@link #getSystemService} to retrieve an
      * {@link android.app.backup.IBackupManager IBackupManager} for communicating
      * with the backup mechanism.
@@ -3487,6 +3492,14 @@
     public static final String RADIO_SERVICE = "radio";
 
     /**
+     * Use with {@link #getSystemService} to retrieve a
+     * {@link android.os.HardwarePropertiesManager} for accessing the hardware properties service.
+     *
+     * @see #getSystemService
+     */
+    public static final String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 381ea90..06da4955 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -664,10 +664,13 @@
     public static final String ACTION_DEFAULT = ACTION_VIEW;
 
     /**
-     * Activity Action: Quick view the data.
-     * <p>Input: {@link #getData} is URI from which to retrieve data.
+     * Activity Action: Quick view the data. Launches a quick viewer for
+     * a URI or a list of URIs.
+     * <p>Input: {@link #getData} is a mandatory content URI of the item to
+     * preview. {@link #getClipData} contains an optional list of content URIs
+     * if there is more than one item to preview. {@link #EXTRA_INDEX} is an
+     * optional index of the URI in the clip data to show first.
      * <p>Output: nothing.
-     * @hide
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
@@ -3029,27 +3032,15 @@
 
     /**
      * Broadcast sent to the primary user when an associated managed profile's availability has
-     * changed. This includes when the user toggles the profile's quiet mode, or when the profile
-     * owner suspends the profile. Carries an extra {@link #EXTRA_USER} that specifies the
-     * UserHandle of the profile. When quiet mode is changed, this broadcast will carry a boolean
-     * extra {@link #EXTRA_QUIET_MODE} indicating the new state of quiet mode. This is only sent to
-     * registered receivers, not manifest receivers.
+     * 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,
+     * this broadcast will carry a boolean extra {@link #EXTRA_QUIET_MODE} indicating the new state
+     * of quiet mode. This is only sent to registered receivers, not manifest receivers.
      */
     public static final String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED =
             "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
 
     /**
-     * Broadcast sent to the managed profile when its availability has changed. This includes when
-     * the user toggles the profile's quiet mode, or when the profile owner suspends the profile.
-     * When quiet mode is changed, this broadcast will carry a boolean extra
-     * {@link #EXTRA_QUIET_MODE} indicating the new state of quiet mode. This is only sent to
-     * registered receivers, not manifest receivers. See also
-     * {@link #ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED}
-     */
-    public static final String ACTION_AVAILABILITY_CHANGED =
-            "android.intent.action.AVAILABILITY_CHANGED";
-
-    /**
      * Sent when the user taps on the clock widget in the system's "quick settings" area.
      */
     public static final String ACTION_QUICK_CLOCK =
@@ -4159,7 +4150,10 @@
     public static final String EXTRA_SIM_ACTIVATION_RESPONSE =
             "android.intent.extra.SIM_ACTIVATION_RESPONSE";
 
-    /** {@hide} */
+    /**
+     * Optional index with semantics depending on the intent action.
+     * @see #ACTION_QUICK_VIEW
+     */
     public static final String EXTRA_INDEX = "android.intent.extra.INDEX";
 
     /**
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 0168908..654396b 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -176,7 +176,7 @@
     
     /**
      * Value for {@link #flags}: this is set if this application has been
-     * install as an update to a built-in system application.
+     * installed as an update to a built-in system application.
      */
     public static final int FLAG_UPDATED_SYSTEM_APP = 1<<7;
     
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 89f6870..476dc46 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1545,6 +1545,14 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports host-
+     * based NFC-F card emulation.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device supports the OpenGL ES
      * <a href="http://www.khronos.org/registry/gles/extensions/ANDROID/ANDROID_extension_pack_es31a.txt">
      * Android Extension Pack</a>.
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index ed64ead..e404429 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -162,10 +162,6 @@
 
     private final Configuration mConfiguration = new Configuration();
 
-    // Invariant: mResolvedLocale is the resolved locale of mLocalesForResolved
-    private LocaleList mLocalesForResolved = null;
-    private Locale mResolvedLocale = null;
-
     private PluralRules mPluralRule;
 
     private CompatibilityInfo mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
@@ -321,16 +317,6 @@
     }
 
     /**
-     * Return the Locale resulting from locale negotiation between the Resources and the
-     * Configuration objects used to construct the Resources. The locale is used for retrieving
-     * resources as well as for determining plural rules.
-     */
-    @NonNull
-    public Locale getResolvedLocale() {
-        return mResolvedLocale;
-    }
-
-    /**
      * Return the string value associated with a particular resource ID.  The
      * returned object will be a String if this is a plain string; it will be
      * some other type of CharSequence if it is styled.
@@ -394,7 +380,7 @@
     private PluralRules getPluralRule() {
         synchronized (sSync) {
             if (mPluralRule == null) {
-                mPluralRule = PluralRules.forLocale(mResolvedLocale);
+                mPluralRule = PluralRules.forLocale(mConfiguration.getLocales().getPrimary());
             }
             return mPluralRule;
         }
@@ -457,7 +443,7 @@
     @NonNull
     public String getString(@StringRes int id, Object... formatArgs) throws NotFoundException {
         final String raw = getString(id);
-        return String.format(mResolvedLocale, raw, formatArgs);
+        return String.format(mConfiguration.getLocales().getPrimary(), raw, formatArgs);
     }
 
     /**
@@ -488,7 +474,7 @@
     public String getQuantityString(@PluralsRes int id, int quantity, Object... formatArgs)
             throws NotFoundException {
         String raw = getQuantityText(id, quantity).toString();
-        return String.format(mResolvedLocale, raw, formatArgs);
+        return String.format(mConfiguration.getLocales().getPrimary(), raw, formatArgs);
     }
 
     /**
@@ -1955,7 +1941,7 @@
 
             LocaleList locales = mConfiguration.getLocales();
             if (locales.isEmpty()) {
-                locales = LocaleList.getDefault();
+                locales = LocaleList.getAdjustedDefault();
                 mConfiguration.setLocales(locales);
             }
             if (mConfiguration.densityDpi != Configuration.DENSITY_DPI_UNDEFINED) {
@@ -1983,26 +1969,8 @@
                 keyboardHidden = mConfiguration.keyboardHidden;
             }
 
-            if (locales != mLocalesForResolved) {
-                if (locales.size() == 1) {
-                    // This is an optimization to avoid the JNI call(s) when the result of
-                    // getFirstMatchWithEnglishSupported() does not depend on the supported locales.
-                    mResolvedLocale = locales.getPrimary();
-                } else {
-                    String[] supportedLocales = mAssets.getNonSystemLocales();
-                    if (LocaleList.isPseudoLocalesOnly(supportedLocales)) {
-                        // We fallback to all locales (including system locales) if there was no
-                        // locale specifically supported by the assets. This is to properly support
-                        // apps that only rely on the shared system assets and don't need assets of
-                        // their own.
-                        supportedLocales = mAssets.getLocales();
-                    }
-                    mResolvedLocale = locales.getFirstMatchWithEnglishSupported(supportedLocales);
-                }
-                mLocalesForResolved = locales;
-            }
             mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc,
-                    adjustLanguageTag(mResolvedLocale.toLanguageTag()),
+                    adjustLanguageTag(locales.getPrimary().toLanguageTag()),
                     mConfiguration.orientation,
                     mConfiguration.touchscreen,
                     mConfiguration.densityDpi, mConfiguration.keyboard,
@@ -2027,7 +1995,7 @@
         }
         synchronized (sSync) {
             if (mPluralRule != null) {
-                mPluralRule = PluralRules.forLocale(mResolvedLocale);
+                mPluralRule = PluralRules.forLocale(mConfiguration.getLocales().getPrimary());
             }
         }
     }
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 6935174..e5efd56 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -551,6 +551,29 @@
      */
     public static final String STRING_TYPE_DEVICE_ORIENTATION = "android.sensor.device_orientation";
 
+     /**
+     * A constant describing a pose sensor with 6 degrees of freedom.
+     *
+     * Similar to {@link #TYPE_ROTATION_VECTOR}, with additional delta
+     * translation from an arbitrary reference point.
+     *
+     * Can use camera, depth sensor etc to compute output value.
+     *
+     * This is expected to be a high power sensor and expected only to be
+     * used when the screen is on.
+     *
+     * Expected to be more accurate than the rotation vector alone.
+     *
+     */
+    public static final int TYPE_POSE_6DOF = 28;
+
+    /**
+     * A constant string describing a pose sensor with 6 degrees of freedom.
+     *
+     * @see #TYPE_POSE_6DOF
+     */
+    public static final String STRING_TYPE_POSE_6DOF = "android.sensor.pose_6dof";
+
     /**
      * A constant describing all sensor types.
      */
@@ -637,6 +660,7 @@
             1, // SENSOR_TYPE_PICK_UP_GESTURE
             1, // SENSOR_TYPE_WRIST_TILT_GESTURE
             1, // SENSOR_TYPE_DEVICE_ORIENTATION
+            16, // SENSOR_TYPE_POSE_6DOF
     };
 
     /**
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 9937b2c..416c74c 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -497,6 +497,40 @@
      * <li> 3: device is rotated 90 degrees clockwise from default orientation (X axis
      *         is vertical and points down)
      * </ul>
+     *
+     *   <h4>{@link android.hardware.Sensor#TYPE_POSE_6DOF
+     * Sensor.TYPE_POSE_6DOF}:</h4>
+     *
+     * A TYPE_POSE_6DOF event consists of a rotation expressed as a quaternion and a translation
+     * expressed in SI units. The event also contains a delta rotation and translation that show
+     * how the device?s pose has changed since the previous sequence numbered pose.
+     * The event uses the cannonical Android Sensor axes.
+     *
+     *
+     * <ul>
+     *  <li> values[0]: x*sin(&#952/2) </li>
+     *  <li> values[1]: y*sin(&#952/2) </li>
+     *  <li> values[2]: z*sin(&#952/2) </li>
+     *  <li> values[3]: cos(&#952/2)   </li>
+     *
+     *
+     * <li> values[4]: Translation along x axis from an arbitrary origin. </li>
+     * li> values[5]: Translation along y axis from an arbitrary origin. </li>
+     * <li> values[6]: Translation along z axis from an arbitrary origin. </li>
+     *
+     * <li> values[7]:  Delta quaternion rotation x*sin(&#952/2) </li>
+     * <li> values[8]:  Delta quaternion rotation y*sin(&#952/2) </li>
+     * <li> values[9]:  Delta quaternion rotation z*sin(&#952/2) </li>
+     * <li> values[10]: Delta quaternion rotation cos(&#952/2) </li>
+     *
+     * <li> values[11]: Delta translation along x axis. </li>
+     * <li> values[12]: Delta translation along y axis. </li>
+     * <li> values[13]: Delta translation along z axis. </li>
+     *
+     * <li> values[14]: Sequence number </li>
+     *
+     * </ul>
+     *
      */
     public final float[] values;
 
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index bb0a04f..2aa6af6 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -743,6 +743,26 @@
             new Key<int[]>("android.control.availableModes", int[].class);
 
     /**
+     * <p>Range of boosts for {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost} supported
+     * by this camera device.</p>
+     * <p>Devices support post RAW sensitivity boost  will advertise
+     * {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost} key for controling
+     * post RAW sensitivity boost.</p>
+     * <p>This key will be <code>null</code> for devices that do not support any RAW format
+     * outputs. For devices that do support RAW format outputs, this key will always
+     * present, and if a device does not support post RAW sensitivity boost, it will
+     * list <code>(100, 100)</code> in this key.</p>
+     * <p><b>Units</b>: ISO arithmetic units, the same as {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST
+     * @see CaptureRequest#SENSOR_SENSITIVITY
+     */
+    @PublicKey
+    public static final Key<android.util.Range<Integer>> CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE =
+            new Key<android.util.Range<Integer>>("android.control.postRawSensitivityBoostRange", new TypeReference<android.util.Range<Integer>>() {{ }});
+
+    /**
      * <p>List of edge enhancement modes for {@link CaptureRequest#EDGE_MODE android.edge.mode} that are supported by this camera
      * device.</p>
      * <p>Full-capability camera devices must always support OFF; camera devices that support
@@ -2767,22 +2787,39 @@
 
     /**
      * <p>Generally classifies the overall set of the camera device functionality.</p>
-     * <p>Camera devices will come in three flavors: LEGACY, LIMITED and FULL.</p>
-     * <p>A FULL device will support below capabilities:</p>
+     * <p>The supported hardware level is a high-level description of the camera device's
+     * capabilities, summarizing several capabilities into one field.  Each level adds additional
+     * features to the previous one, and is always a strict superset of the previous level.
+     * The ordering is <code>LEGACY &lt; LIMITED &lt; FULL &lt; LEVEL_3</code>.</p>
+     * <p>Starting from <code>LEVEL_3</code>, the level enumerations are guaranteed to be in increasing
+     * numerical value as well. To check if a given device is at least at a given hardware level,
+     * the following code snippet can be used:</p>
+     * <pre><code>// Returns true if the device supports the required hardware level, or better.
+     * boolean isHardwareLevelSupported(CameraCharacteristics c, int requiredLevel) {
+     *     int deviceLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+     *     if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
+     *         return requiredLevel == deviceLevel;
+     *     }
+     *     // deviceLevel is not LEGACY, can use numerical sort
+     *     return requiredLevel &lt;= deviceLevel;
+     * }
+     * </code></pre>
+     * <p>At a high level, the levels are:</p>
      * <ul>
-     * <li>BURST_CAPTURE capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains BURST_CAPTURE)</li>
-     * <li>Per frame control ({@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} <code>==</code> PER_FRAME_CONTROL)</li>
-     * <li>Manual sensor control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR)</li>
-     * <li>Manual post-processing control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
-     *   MANUAL_POST_PROCESSING)</li>
-     * <li>At least 3 processed (but not stalling) format output streams
-     *   ({@link CameraCharacteristics#REQUEST_MAX_NUM_OUTPUT_PROC android.request.maxNumOutputProc} <code>&gt;=</code> 3)</li>
-     * <li>The required stream configurations defined in android.scaler.availableStreamConfigurations</li>
-     * <li>The required exposure time range defined in {@link CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE android.sensor.info.exposureTimeRange}</li>
-     * <li>The required maxFrameDuration defined in {@link CameraCharacteristics#SENSOR_INFO_MAX_FRAME_DURATION android.sensor.info.maxFrameDuration}</li>
+     * <li><code>LEGACY</code> devices operate in a backwards-compatibility mode for older
+     *   Android devices, and have very limited capabilities.</li>
+     * <li><code>LIMITED</code> devices represent the
+     *   baseline feature set, and may also include additional capabilities that are
+     *   subsets of <code>FULL</code>.</li>
+     * <li><code>FULL</code> devices additionally support per-frame manual control of sensor, flash, lens and
+     *   post-processing settings, and image capture at a high rate.</li>
+     * <li><code>LEVEL_3</code> devices additionally support YUV reprocessing and RAW image capture, along
+     *   with additional output stream configurations.</li>
      * </ul>
-     * <p>A LIMITED device may have some or none of the above characteristics.
-     * To find out more refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
+     * <p>See the individual level enums for full descriptions of the supported capabilities.  The
+     * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} entry describes the device's capabilities at a
+     * finer-grain level, if needed. In addition, many controls have their available settings or
+     * ranges defined in individual {@link android.hardware.camera2.CameraCharacteristics } entries.</p>
      * <p>Some features are not part of any particular hardware level or capability and must be
      * queried separately. These include:</p>
      * <ul>
@@ -2793,19 +2830,12 @@
      *   ({@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization},
      *    {@link CameraCharacteristics#CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES android.control.availableVideoStabilizationModes})</li>
      * </ul>
-     * <p>A LEGACY device does not support per-frame control, manual sensor control, manual
-     * post-processing, arbitrary cropping regions, and has relaxed performance constraints.</p>
-     * <p>Each higher level supports everything the lower level supports
-     * in this order: FULL <code>&gt;</code> LIMITED <code>&gt;</code> LEGACY.</p>
-     * <p>Note:
-     * Pre-API level 23, FULL devices also supported arbitrary cropping region
-     * ({@link CameraCharacteristics#SCALER_CROPPING_TYPE android.scaler.croppingType} <code>==</code> FREEFORM); this requirement was relaxed in API level 23,
-     * and FULL devices may only support CENTERED cropping.</p>
      * <p><b>Possible values:</b>
      * <ul>
      *   <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED}</li>
      *   <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}</li>
      *   <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}</li>
+     *   <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_3 3}</li>
      * </ul></p>
      * <p>This key is available on all devices.</p>
      *
@@ -2813,16 +2843,12 @@
      * @see CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
      * @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
-     * @see CameraCharacteristics#REQUEST_MAX_NUM_OUTPUT_PROC
-     * @see CameraCharacteristics#SCALER_CROPPING_TYPE
-     * @see CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE
-     * @see CameraCharacteristics#SENSOR_INFO_MAX_FRAME_DURATION
      * @see CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE
      * @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES
-     * @see CameraCharacteristics#SYNC_MAX_LATENCY
      * @see #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
      * @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL
      * @see #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
+     * @see #INFO_SUPPORTED_HARDWARE_LEVEL_3
      */
     @PublicKey
     public static final Key<Integer> INFO_SUPPORTED_HARDWARE_LEVEL =
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 852a4d9..28bb22a 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -314,7 +314,7 @@
      * </table><br>
      * </p>
      *
-     * <p>Limited-capability ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+     * <p>Limited-level ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
      * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED}) devices
      * support at least the following stream combinations in addition to those for
      * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY} devices:
@@ -332,13 +332,13 @@
      * </table><br>
      * </p>
      *
-     * <p>FULL-capability ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+     * <p>FULL-level ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
      * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}) devices
      * support at least the following stream combinations in addition to those for
      * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED} devices:
      *
      * <table>
-     * <tr><th colspan="7">FULL-capability additional guaranteed configurations</th></tr>
+     * <tr><th colspan="7">FULL-level additional guaranteed configurations</th></tr>
      * <tr><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th> <th rowspan="2">Sample use case(s)</th> </tr>
      * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th> </tr>
      * <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td colspan="2" id="rb"></td> <td>Maximum-resolution GPU processing with preview.</td> </tr>
@@ -389,6 +389,22 @@
      * </table><br>
      * </p>
      *
+     * <p>LEVEL-3 ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+     * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_3 LEVEL_3})
+     * support at least the following stream combinations in addition to the combinations for
+     * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL} and for
+     * RAW capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES} includes
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_RAW RAW}):
+     *
+     * <table>
+     * <tr><th colspan="11">LEVEL-3 additional guaranteed configurations</th></tr>
+     * <tr><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th rowspan="2">Sample use case(s)</th> </tr>
+     * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th> </tr>
+     * <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code 640x480}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td>In-app viewfinder analysis with dynamic selection of output format.</td> </tr>
+     * <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code 640x480}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td>In-app viewfinder analysis with dynamic selection of output format.</td> </tr>
+     * </table><br>
+     * </p>
+     *
      * <p>Since the capabilities of camera devices vary greatly, a given camera device may support
      * target combinations with sizes outside of these guarantees, but this can only be tested for
      * by attempting to create a session with such targets.</p>
@@ -421,8 +437,6 @@
      *
      * @see #createCaptureSession
      * @see OutputConfiguration
-     *
-     * @hide
      */
     public abstract void createCaptureSessionByOutputConfiguration(
             List<OutputConfiguration> outputConfigurations,
@@ -503,7 +517,7 @@
      *  #rb { border-right-width: thick; }
      * </style>
      *
-     * <p>Limited-capability ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+     * <p>LIMITED-level ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
      * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED}) devices
      * support at least the following stream combinations for creating a reprocessable capture
      * session in addition to those listed in {@link #createCaptureSession createCaptureSession} for
@@ -520,14 +534,14 @@
      * </table><br>
      * </p>
      *
-     * <p>FULL-capability ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+     * <p>FULL-level ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
      * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}) devices
      * support at least the following stream combinations for creating a reprocessable capture
      * session in addition to those for
      * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED} devices:
      *
      * <table>
-     * <tr><th colspan="11">FULL-capability additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr>
+     * <tr><th colspan="11">FULL-level additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr>
      * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th rowspan="2">Sample use case(s)</th> </tr>
      * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr>
      * <tr> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td></td><td id="rb"></td> <td></td><td id="rb"></td> <td>Maximum-resolution multi-frame image fusion in-app processing with regular preview.</td> </tr>
@@ -557,6 +571,22 @@
      * </table><br>
      * </p>
      *
+     * <p>LEVEL-3 ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+     * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_3 LEVEL_3}) devices
+     * support at least the following stream combinations for creating a reprocessable capture
+     * session in addition to those for
+     * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL} devices. Note that targets in the "Reprocess-only target" column may only be
+     * used as an output target for a reprocess capture request, not as an output to a regular capture request.
+     *
+     * <table>
+     * <tr><th colspan="13">LEVEL-3 additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is always guaranteed.</th></tr>
+     * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th colspan="2" id="rb">Reprocess-only target</th><th rowspan="2">Sample use case(s)</th> </tr>
+     * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr>
+     * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code 640x480}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>In-app viewfinder analysis with ZSL and RAW.</td> </tr>
+     * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code 640x480}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td><td>In-app viewfinder analysis with ZSL, RAW, and JPEG reprocessing output.</td> </tr>
+     * </table><br>
+     * </p>
+     *
      * @param inputConfig The configuration for the input {@link Surface}
      * @param outputs The new set of Surfaces that should be made available as
      *                targets for captured image data.
@@ -587,6 +617,22 @@
             throws CameraAccessException;
 
     /**
+     * Create a new reprocessable camera capture session by providing the desired reprocessing
+     * input configuration and output {@link OutputConfiguration}
+     * to the camera device.
+     *
+     * @see #createReprocessableCaptureSession
+     * @see OutputConfiguration
+     *
+     */
+    public abstract void createReprocessableCaptureSessionWithConfigurations(
+            @NonNull InputConfiguration inputConfig,
+            @NonNull List<OutputConfiguration> outputs,
+            @NonNull CameraCaptureSession.StateCallback callback,
+            @Nullable Handler handler)
+            throws CameraAccessException;
+
+    /**
      * <p>Create a new constrained high speed capture session.</p>
      *
      * <p>The application can use normal capture session (created via {@link #createCaptureSession})
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index f61892e..d58ad22 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -964,23 +964,102 @@
     //
 
     /**
-     * <p>This camera device has only limited capabilities.</p>
+     * <p>This camera device does not have enough capabilities to qualify as a <code>FULL</code> device or
+     * better.</p>
+     * <p>Only the stream configurations listed in the <code>LEGACY</code> and <code>LIMITED</code> tables in the
+     * {@link android.hardware.camera2.CameraDevice#createCaptureSession createCaptureSession} documentation are guaranteed to be supported.</p>
+     * <p>All <code>LIMITED</code> devices support the <code>BACKWARDS_COMPATIBLE</code> capability, indicating basic
+     * support for color image capture. The only exception is that the device may
+     * alternatively support only the <code>DEPTH_OUTPUT</code> capability, if it can only output depth
+     * measurements and not color images.</p>
+     * <p><code>LIMITED</code> devices and above require the use of {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}
+     * to lock exposure metering (and calculate flash power, for cameras with flash) before
+     * capturing a high-quality still image.</p>
+     * <p>A <code>LIMITED</code> device that only lists the <code>BACKWARDS_COMPATIBLE</code> capability is only
+     * required to support full-automatic operation and post-processing (<code>OFF</code> is not
+     * supported for {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}, or
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode})</p>
+     * <p>Additional capabilities may optionally be supported by a <code>LIMITED</code>-level device, and
+     * can be checked for in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      */
     public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0;
 
     /**
      * <p>This camera device is capable of supporting advanced imaging applications.</p>
+     * <p>The stream configurations listed in the <code>FULL</code>, <code>LEGACY</code> and <code>LIMITED</code> tables in the
+     * {@link android.hardware.camera2.CameraDevice#createCaptureSession createCaptureSession} documentation are guaranteed to be supported.</p>
+     * <p>A <code>FULL</code> device will support below capabilities:</p>
+     * <ul>
+     * <li><code>BURST_CAPTURE</code> capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+     *   <code>BURST_CAPTURE</code>)</li>
+     * <li>Per frame control ({@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} <code>==</code> PER_FRAME_CONTROL)</li>
+     * <li>Manual sensor control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains <code>MANUAL_SENSOR</code>)</li>
+     * <li>Manual post-processing control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+     *   <code>MANUAL_POST_PROCESSING</code>)</li>
+     * <li>The required exposure time range defined in {@link CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE android.sensor.info.exposureTimeRange}</li>
+     * <li>The required maxFrameDuration defined in {@link CameraCharacteristics#SENSOR_INFO_MAX_FRAME_DURATION android.sensor.info.maxFrameDuration}</li>
+     * </ul>
+     * <p>Note:
+     * Pre-API level 23, FULL devices also supported arbitrary cropping region
+     * ({@link CameraCharacteristics#SCALER_CROPPING_TYPE android.scaler.croppingType} <code>== FREEFORM</code>); this requirement was relaxed in API level
+     * 23, and <code>FULL</code> devices may only support <code>CENTERED</code> cropping.</p>
+     *
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @see CameraCharacteristics#SCALER_CROPPING_TYPE
+     * @see CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE
+     * @see CameraCharacteristics#SENSOR_INFO_MAX_FRAME_DURATION
+     * @see CameraCharacteristics#SYNC_MAX_LATENCY
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      */
     public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1;
 
     /**
      * <p>This camera device is running in backward compatibility mode.</p>
+     * <p>Only the stream configurations listed in the <code>LEGACY</code> table in the {@link android.hardware.camera2.CameraDevice#createCaptureSession createCaptureSession}
+     * documentation are supported.</p>
+     * <p>A <code>LEGACY</code> device does not support per-frame control, manual sensor control, manual
+     * post-processing, arbitrary cropping regions, and has relaxed performance constraints.
+     * No additional capabilities beyond <code>BACKWARD_COMPATIBLE</code> will ever be listed by a
+     * <code>LEGACY</code> device in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
+     * <p>In addition, the {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is not functional on <code>LEGACY</code>
+     * devices. Instead, every request that includes a JPEG-format output target is treated
+     * as triggering a still capture, internally executing a precapture trigger.  This may
+     * fire the flash for flash power metering during precapture, and then fire the flash
+     * for the final capture, if a flash is available on the device and the AE mode is set to
+     * enable the flash.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      */
     public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2;
 
+    /**
+     * <p>This camera device is capable of YUV reprocessing and RAW data capture, in addition to
+     * FULL-level capabilities.</p>
+     * <p>The stream configurations listed in the <code>LEVEL_3</code>, <code>RAW</code>, <code>FULL</code>, <code>LEGACY</code> and
+     * <code>LIMITED</code> tables in the {@link android.hardware.camera2.CameraDevice#createCaptureSession createCaptureSession}
+     * documentation are guaranteed to be supported.</p>
+     * <p>The following additional capabilities are guaranteed to be supported:</p>
+     * <ul>
+     * <li><code>YUV_REPROCESSING</code> capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+     *   <code>YUV_REPROCESSING</code>)</li>
+     * <li><code>RAW</code> capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+     *   <code>RAW</code>)</li>
+     * </ul>
+     *
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+     */
+    public static final int INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3;
+
     //
     // Enumeration values for CameraCharacteristics#SYNC_MAX_LATENCY
     //
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 67835a0..79eff4f 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1590,6 +1590,41 @@
             new Key<Integer>("android.control.videoStabilizationMode", int.class);
 
     /**
+     * <p>The amount of additional sesnsitivity boost applied to output images
+     * after RAW sensor data is captured.</p>
+     * <p>Some camera devices support additional digital sensitivity boosting in the
+     * camera processing pipeline after sensor RAW image is captured.
+     * Such a boost will be applied to YUV/JPEG format output images but will not
+     * have effect on RAW output formats like RAW_SENSOR, RAW10, RAW12 or RAW_OPAQUE.</p>
+     * <p>This key is optional. Applications can assume there is no boost applied
+     * after RAW is captured if this key is not available.
+     * When this key is available, the sensitivity boost value must be within
+     * {@link CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE android.control.postRawSensitivityBoostRange}.</p>
+     * <p>If the camera device cannot apply the exact boost requested, it will reduce the
+     * boost to the nearest supported value.
+     * The final boost value used will be available in the output capture result.</p>
+     * <p>For devices that support post RAW sensitivity boost, the YUV/JPEG output images
+     * of such device will have the total sensitivity of
+     * <code>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} * {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost} / 100</code>
+     * The sensitivity of RAW format images will always be <code>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</code></p>
+     * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
+     * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+     * <p><b>Units</b>: ISO arithmetic units, the same as {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</p>
+     * <p><b>Range of valid values:</b><br>
+     * {@link CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE android.control.postRawSensitivityBoostRange}</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST
+     * @see CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE
+     * @see CaptureRequest#SENSOR_SENSITIVITY
+     */
+    @PublicKey
+    public static final Key<Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST =
+            new Key<Integer>("android.control.postRawSensitivityBoost", int.class);
+
+    /**
      * <p>Operation mode for edge
      * enhancement.</p>
      * <p>Edge enhancement improves sharpness and details in the captured image. OFF means
@@ -2244,6 +2279,8 @@
      * requested, it will reduce the gain to the nearest supported
      * value. The final sensitivity used will be available in the
      * output capture result.</p>
+     * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
+     * OFF; otherwise the auto-exposure algorithm will override this value.</p>
      * <p><b>Units</b>: ISO arithmetic units</p>
      * <p><b>Range of valid values:</b><br>
      * {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}</p>
@@ -2252,6 +2289,8 @@
      * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
      * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
      *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_MODE
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      * @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
      * @see CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 3c2d503..5748726 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2097,6 +2097,41 @@
             new Key<Integer>("android.control.videoStabilizationMode", int.class);
 
     /**
+     * <p>The amount of additional sesnsitivity boost applied to output images
+     * after RAW sensor data is captured.</p>
+     * <p>Some camera devices support additional digital sensitivity boosting in the
+     * camera processing pipeline after sensor RAW image is captured.
+     * Such a boost will be applied to YUV/JPEG format output images but will not
+     * have effect on RAW output formats like RAW_SENSOR, RAW10, RAW12 or RAW_OPAQUE.</p>
+     * <p>This key is optional. Applications can assume there is no boost applied
+     * after RAW is captured if this key is not available.
+     * When this key is available, the sensitivity boost value must be within
+     * {@link CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE android.control.postRawSensitivityBoostRange}.</p>
+     * <p>If the camera device cannot apply the exact boost requested, it will reduce the
+     * boost to the nearest supported value.
+     * The final boost value used will be available in the output capture result.</p>
+     * <p>For devices that support post RAW sensitivity boost, the YUV/JPEG output images
+     * of such device will have the total sensitivity of
+     * <code>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} * {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost} / 100</code>
+     * The sensitivity of RAW format images will always be <code>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</code></p>
+     * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
+     * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+     * <p><b>Units</b>: ISO arithmetic units, the same as {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</p>
+     * <p><b>Range of valid values:</b><br>
+     * {@link CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE android.control.postRawSensitivityBoostRange}</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST
+     * @see CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE
+     * @see CaptureRequest#SENSOR_SENSITIVITY
+     */
+    @PublicKey
+    public static final Key<Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST =
+            new Key<Integer>("android.control.postRawSensitivityBoost", int.class);
+
+    /**
      * <p>Operation mode for edge
      * enhancement.</p>
      * <p>Edge enhancement improves sharpness and details in the captured image. OFF means
@@ -3086,6 +3121,8 @@
      * requested, it will reduce the gain to the nearest supported
      * value. The final sensitivity used will be available in the
      * output capture result.</p>
+     * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
+     * OFF; otherwise the auto-exposure algorithm will override this value.</p>
      * <p><b>Units</b>: ISO arithmetic units</p>
      * <p><b>Range of valid values:</b><br>
      * {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}</p>
@@ -3094,6 +3131,8 @@
      * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
      * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
      *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_MODE
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      * @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
      * @see CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index c3a4954..3aba0d1 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -485,7 +485,13 @@
             Log.d(TAG, "createCaptureSessionByOutputConfiguration");
         }
 
-        createCaptureSessionInternal(null, outputConfigurations, callback, handler,
+        // OutputConfiguration objects aren't immutable, make a copy before using.
+        List<OutputConfiguration> currentOutputs = new ArrayList<OutputConfiguration>();
+        for (OutputConfiguration output : outputConfigurations) {
+            currentOutputs.add(new OutputConfiguration(output));
+        }
+
+        createCaptureSessionInternal(null, currentOutputs, callback, handler,
                 /*isConstrainedHighSpeed*/false);
     }
 
@@ -510,6 +516,34 @@
     }
 
     @Override
+    public void createReprocessableCaptureSessionWithConfigurations(InputConfiguration inputConfig,
+            List<OutputConfiguration> outputs,
+            android.hardware.camera2.CameraCaptureSession.StateCallback callback, Handler handler)
+                    throws CameraAccessException {
+        if (DEBUG) {
+            Log.d(TAG, "createReprocessableCaptureSessionWithConfigurations");
+        }
+
+        if (inputConfig == null) {
+            throw new IllegalArgumentException("inputConfig cannot be null when creating a " +
+                    "reprocessable capture session");
+        }
+
+        if (outputs == null) {
+            throw new IllegalArgumentException("Output configurations cannot be null when " +
+                    "creating a reprocessable capture session");
+        }
+
+        // OutputConfiguration objects aren't immutable, make a copy before using.
+        List<OutputConfiguration> currentOutputs = new ArrayList<OutputConfiguration>();
+        for (OutputConfiguration output : outputs) {
+            currentOutputs.add(new OutputConfiguration(output));
+        }
+        createCaptureSessionInternal(inputConfig, currentOutputs,
+                callback, handler, /*isConstrainedHighSpeed*/false);
+    }
+
+    @Override
     public void createConstrainedHighSpeedCaptureSession(List<Surface> outputs,
             android.hardware.camera2.CameraCaptureSession.StateCallback callback, Handler handler)
             throws CameraAccessException {
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index a04cdce..4407e55 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -17,6 +17,7 @@
 
 package android.hardware.camera2.params;
 
+import android.annotation.SystemApi;
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.utils.HashCodeHelpers;
 import android.hardware.camera2.utils.SurfaceUtils;
@@ -32,39 +33,58 @@
  * A class for describing camera output, which contains a {@link Surface} and its specific
  * configuration for creating capture session.
  *
- * @see CameraDevice#createCaptureSession
+ * @see CameraDevice#createCaptureSessionByOutputConfiguration
  *
- * @hide
  */
 public final class OutputConfiguration implements Parcelable {
 
     /**
      * Rotation constant: 0 degree rotation (no rotation)
+     *
+     * @hide
      */
+    @SystemApi
     public static final int ROTATION_0 = 0;
 
     /**
      * Rotation constant: 90 degree counterclockwise rotation.
+     *
+     * @hide
      */
+    @SystemApi
     public static final int ROTATION_90 = 1;
 
     /**
      * Rotation constant: 180 degree counterclockwise rotation.
+     *
+     * @hide
      */
+    @SystemApi
     public static final int ROTATION_180 = 2;
 
     /**
      * Rotation constant: 270 degree counterclockwise rotation.
+     *
+     * @hide
      */
+    @SystemApi
     public static final int ROTATION_270 = 3;
 
     /**
-     * Create a new immutable SurfaceConfiguration instance.
+     * Invalid surface set ID.
+     *
+     *<p>An {@link OutputConfiguration} with this value indicates that the included surface
+     *doesn't belong to any surface set.</p>
+     */
+    public static final int SURFACE_SET_ID_INVALID = -1;
+
+    /**
+     * Create a new {@link OutputConfiguration} instance with a {@link Surface}.
      *
      * @param surface
      *          A Surface for camera to output to.
      *
-     * <p>This constructor creates a default configuration</p>
+     * <p>This constructor creates a default configuration.</p>
      *
      */
     public OutputConfiguration(Surface surface) {
@@ -72,7 +92,7 @@
     }
 
     /**
-     * Create a new immutable SurfaceConfiguration instance.
+     * Create a new {@link OutputConfiguration} instance.
      *
      * <p>This constructor takes an argument for desired camera rotation</p>
      *
@@ -87,11 +107,13 @@
      *          application should set rotation to {@code ROTATION_90} and make sure the
      *          corresponding Surface size is 720x1280. Note that {@link CameraDevice} might
      *          throw {@code IllegalArgumentException} if device cannot perform such rotation.
-     *
+     * @hide
      */
+    @SystemApi
     public OutputConfiguration(Surface surface, int rotation) {
         checkNotNull(surface, "Surface must not be null");
         checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
+        mSurfaceSetId = SURFACE_SET_ID_INVALID;
         mSurface = surface;
         mRotation = rotation;
         mConfiguredSize = SurfaceUtils.getSurfaceSize(surface);
@@ -100,13 +122,37 @@
     }
 
     /**
+     * Create a new {@link OutputConfiguration} instance with another {@link OutputConfiguration}
+     * instance.
+     *
+     * @param other Another {@link OutputConfiguration} instance to be copied.
+     *
+     * @hide
+     */
+    @SystemApi
+    public OutputConfiguration(OutputConfiguration other) {
+        if (other == null) {
+            throw new IllegalArgumentException("OutputConfiguration shouldn't be null");
+        }
+
+        this.mSurface = other.mSurface;
+        this.mRotation = other.mRotation;
+        this.mSurfaceSetId = other.mSurfaceSetId;
+        this.mConfiguredDataspace = other.mConfiguredDataspace;
+        this.mConfiguredFormat = other.mConfiguredFormat;
+        this.mConfiguredSize = other.mConfiguredSize;
+    }
+
+    /**
      * Create an OutputConfiguration from Parcel.
      */
     private OutputConfiguration(Parcel source) {
         int rotation = source.readInt();
+        int surfaceSetId = source.readInt();
         Surface surface = Surface.CREATOR.createFromParcel(source);
         checkNotNull(surface, "Surface must not be null");
         checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
+        mSurfaceSetId = surfaceSetId;
         mSurface = surface;
         mRotation = rotation;
         mConfiguredSize = SurfaceUtils.getSurfaceSize(mSurface);
@@ -128,11 +174,46 @@
      *
      * @return the rotation associated with this {@link OutputConfiguration}.
      *         Value will be one of ROTATION_[0, 90, 180, 270]
+     *
+     * @hide
      */
+    @SystemApi
     public int getRotation() {
         return mRotation;
     }
 
+    /**
+     * Set the surface set ID to this {@link OutputConfiguration}.
+     *
+     * <p>
+     * A surface set ID is used to identify which surface set this output surface belongs to. A
+     * surface set is a group of output surfaces that are not intended to receive camera output
+     * buffer streams simultaneously. The {@link CameraDevice} may be able to share the buffers used
+     * by all the surfaces from the same surface set, therefore may save the overall memory
+     * footprint. The application should only set the same set ID for the streams that are not
+     * simultaneously streaming. A negative ID indicates that this surface doesn't belong to any
+     * surface set. The default value will be {@value #SURFACE_SET_ID_INVALID}.
+     * </p>
+     *
+     * @param setId
+     */
+    public void setSurfaceSetId(int setId) {
+        if (setId < 0) {
+            setId = SURFACE_SET_ID_INVALID;
+        }
+        mSurfaceSetId = setId;
+    }
+
+    /**
+     * Get the surface set Id associated with this {@link OutputConfiguration}.
+     *
+     * @return the surface set Id associated with this {@link OutputConfiguration}.
+     *         Value will be one of ROTATION_[0, 90, 180, 270]
+     */
+    public int getSurfaceSetId() {
+        return mSurfaceSetId;
+    }
+
     public static final Parcelable.Creator<OutputConfiguration> CREATOR =
             new Parcelable.Creator<OutputConfiguration>() {
         @Override
@@ -163,6 +244,7 @@
             throw new IllegalArgumentException("dest must not be null");
         }
         dest.writeInt(mRotation);
+        dest.writeInt(mSurfaceSetId);
         mSurface.writeToParcel(dest, flags);
     }
 
@@ -187,7 +269,8 @@
                    mRotation == other.mRotation &&
                    mConfiguredSize.equals(other.mConfiguredSize) &&
                    mConfiguredFormat == other.mConfiguredFormat &&
-                   mConfiguredDataspace == other.mConfiguredDataspace;
+                   mConfiguredDataspace == other.mConfiguredDataspace &&
+                   mSurfaceSetId == other.mSurfaceSetId;
         }
         return false;
     }
@@ -203,6 +286,7 @@
     private static final String TAG = "OutputConfiguration";
     private final Surface mSurface;
     private final int mRotation;
+    private int mSurfaceSetId;
 
     // The size, format, and dataspace of the surface when OutputConfiguration is created.
     private final Size mConfiguredSize;
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 04caa8f..9f8c28e 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -491,12 +491,16 @@
      * credentials (e.g. pin, pattern or password).
      * @param cancel an object that can be used to cancel enrollment
      * @param flags optional flags
+     * @param userId the user to whom this fingerprint will belong to
      * @param callback an object to receive enrollment events
      * @hide
      */
     @RequiresPermission(MANAGE_FINGERPRINT)
     public void enroll(byte [] token, CancellationSignal cancel, int flags,
-            EnrollmentCallback callback) {
+            int userId, EnrollmentCallback callback) {
+        if (userId == UserHandle.USER_CURRENT) {
+            userId = getCurrentUserId();
+        }
         if (callback == null) {
             throw new IllegalArgumentException("Must supply an enrollment callback");
         }
@@ -512,7 +516,7 @@
 
         if (mService != null) try {
             mEnrollmentCallback = callback;
-            mService.enroll(mToken, token, getCurrentUserId(), mServiceReceiver, flags);
+            mService.enroll(mToken, token, userId, mServiceReceiver, flags);
         } catch (RemoteException e) {
             Log.w(TAG, "Remote exception in enroll: ", e);
             if (callback != null) {
@@ -556,19 +560,35 @@
     }
 
     /**
+     * Sets the active user. This is meant to be used to select the current profile for enrollment
+     * to allow separate enrolled fingers for a work profile
+     * @param userId
+     * @hide
+     */
+    @RequiresPermission(MANAGE_FINGERPRINT)
+    public void setActiveUser(int userId) {
+        if (mService != null) try {
+            mService.setActiveUser(userId);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Remote exception in setActiveUser: ", e);
+        }
+    }
+
+    /**
      * Remove given fingerprint template from fingerprint hardware and/or protected storage.
      * @param fp the fingerprint item to remove
+     * @param userId the user who this fingerprint belongs to
      * @param callback an optional callback to verify that fingerprint templates have been
      * successfully removed. May be null of no callback is required.
      *
      * @hide
      */
     @RequiresPermission(MANAGE_FINGERPRINT)
-    public void remove(Fingerprint fp, RemovalCallback callback) {
+    public void remove(Fingerprint fp, int userId, RemovalCallback callback) {
         if (mService != null) try {
             mRemovalCallback = callback;
             mRemovalFingerprint = fp;
-            mService.remove(mToken, fp.getFingerId(), getCurrentUserId(), mServiceReceiver);
+            mService.remove(mToken, fp.getFingerId(), userId, mServiceReceiver);
         } catch (RemoteException e) {
             Log.w(TAG, "Remote exception in remove: ", e);
             if (callback != null) {
@@ -581,16 +601,17 @@
     /**
      * Renames the given fingerprint template
      * @param fpId the fingerprint id
+     * @param userId the user who this fingerprint belongs to
      * @param newName the new name
      *
      * @hide
      */
     @RequiresPermission(MANAGE_FINGERPRINT)
-    public void rename(int fpId, String newName) {
+    public void rename(int fpId, int userId, String newName) {
         // Renames the given fpId
         if (mService != null) {
             try {
-                mService.rename(fpId, getCurrentUserId(), newName);
+                mService.rename(fpId, userId, newName);
             } catch (RemoteException e) {
                 Log.v(TAG, "Remote exception in rename(): ", e);
             }
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 690a751..43d5577 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -75,4 +75,7 @@
 
     // Add a callback which gets notified when the fingerprint lockout period expired.
     void addLockoutResetCallback(IFingerprintServiceLockoutResetCallback callback);
+
+    // Explicitly set the active user (for enrolling work profile)
+    void setActiveUser(int uid);
 }
diff --git a/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl b/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl
index 2f6dbe7..597efa5 100644
--- a/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl
+++ b/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl
@@ -25,9 +25,12 @@
     /**
      * Called when the keyphrase is spoken.
      *
-     * @param data Optional trigger audio data, if it was requested and is available.
+     * @param recognitionEvent Object containing data relating to the
+     *                         recognition event such as trigger audio data, if it was requested
+     *                         and is available.
      */
-    void onDetected(in SoundTrigger.KeyphraseRecognitionEvent recognitionEvent);
+    void onDetected(in SoundTrigger.RecognitionEvent recognitionEvent);
+
     /**
      * Called when the detection fails due to an error.
      *
@@ -42,4 +45,4 @@
      * Called when the recognition is resumed after it was temporarily paused.
      */
     void onRecognitionResumed();
-}
\ No newline at end of file
+}
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.aidl b/core/java/android/hardware/soundtrigger/SoundTrigger.aidl
index e16ea71..fec64ea 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.aidl
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.aidl
@@ -18,8 +18,11 @@
 
 parcelable SoundTrigger.ConfidenceLevel;
 parcelable SoundTrigger.Keyphrase;
+parcelable SoundTrigger.RecognitionEvent;
 parcelable SoundTrigger.KeyphraseRecognitionEvent;
+parcelable SoundTrigger.GenericSoundRecognitionEvent;
 parcelable SoundTrigger.KeyphraseRecognitionExtra;
 parcelable SoundTrigger.KeyphraseSoundModel;
+parcelable SoundTrigger.GenericSoundModel;
 parcelable SoundTrigger.ModuleProperties;
 parcelable SoundTrigger.RecognitionConfig;
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index d490409..882908a 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -195,6 +195,12 @@
         /** Keyphrase sound model */
         public static final int TYPE_KEYPHRASE = 0;
 
+        /**
+         * A generic sound model. Use this type only for non-keyphrase sound models such as
+         * ones that match a particular sound pattern.
+         */
+        public static final int TYPE_GENERIC_SOUND = 1;
+
         /** Unique sound model identifier */
         public final UUID uuid;
 
@@ -458,6 +464,63 @@
         }
     }
 
+
+    /*****************************************************************************
+     * A GenericSoundModel is a specialized {@link SoundModel} for non-voice sound
+     * patterns.
+     ****************************************************************************/
+    public static class GenericSoundModel extends SoundModel implements Parcelable {
+
+        public static final Parcelable.Creator<GenericSoundModel> CREATOR
+                = new Parcelable.Creator<GenericSoundModel>() {
+            public GenericSoundModel createFromParcel(Parcel in) {
+                return GenericSoundModel.fromParcel(in);
+            }
+
+            public GenericSoundModel[] newArray(int size) {
+                return new GenericSoundModel[size];
+            }
+        };
+
+        public GenericSoundModel(UUID uuid, UUID vendorUuid, byte[] data) {
+            super(uuid, vendorUuid, TYPE_GENERIC_SOUND, data);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        private static GenericSoundModel fromParcel(Parcel in) {
+            UUID uuid = UUID.fromString(in.readString());
+            UUID vendorUuid = null;
+            int length = in.readInt();
+            if (length >= 0) {
+                vendorUuid = UUID.fromString(in.readString());
+            }
+            byte[] data = in.readBlob();
+            return new GenericSoundModel(uuid, vendorUuid, data);
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(uuid.toString());
+            if (vendorUuid == null) {
+                dest.writeInt(-1);
+            } else {
+                dest.writeInt(vendorUuid.toString().length());
+                dest.writeString(vendorUuid.toString());
+            }
+            dest.writeBlob(data);
+        }
+
+        @Override
+        public String toString() {
+            return "GenericSoundModel [uuid=" + uuid + ", vendorUuid=" + vendorUuid
+                    + ", type=" + type + ", data=" + (data == null ? 0 : data.length) + "]";
+        }
+    }
+
     /**
      *  Modes for key phrase recognition
      */
@@ -1019,6 +1082,21 @@
     }
 
     /**
+     * Sub-class of RecognitionEvent specifically for sound-trigger based sound
+     * models(non-keyphrase). Currently does not contain any additional fields.
+     */
+    public static class GenericRecognitionEvent extends RecognitionEvent {
+        public GenericRecognitionEvent(int status, int soundModelHandle,
+                boolean captureAvailable, int captureSession, int captureDelayMs,
+                int capturePreambleMs, boolean triggerInData, AudioFormat captureFormat,
+                byte[] data) {
+            super(status, soundModelHandle, captureAvailable, captureSession,
+                    captureDelayMs, capturePreambleMs, triggerInData, captureFormat,
+                    data);
+        }
+    }
+
+    /**
      *  Status codes for {@link SoundModelEvent}
      */
     /** Sound Model was updated */
@@ -1118,7 +1196,7 @@
     public static final int SERVICE_STATE_DISABLED = 1;
 
     /**
-     * Returns a list of descriptors for all harware modules loaded.
+     * Returns a list of descriptors for all hardware modules loaded.
      * @param modules A ModuleProperties array where the list will be returned.
      * @return - {@link #STATUS_OK} in case of success
      *         - {@link #STATUS_ERROR} in case of unspecified error
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 5584cde..92c721b 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -16,6 +16,7 @@
 package android.net;
 
 import static com.android.internal.util.Preconditions.checkNotNull;
+
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -27,6 +28,7 @@
 import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -37,6 +39,7 @@
 import android.os.Messenger;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.os.ServiceManager;
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
@@ -338,6 +341,71 @@
     public static final String ACTION_PROMPT_UNVALIDATED = "android.net.conn.PROMPT_UNVALIDATED";
 
     /**
+     * Invalid tethering type.
+     * @see #startTethering(int, OnStartTetheringCallback, boolean)
+     * @hide
+     */
+    public static final int TETHERING_INVALID   = -1;
+
+    /**
+     * Wifi tethering type.
+     * @see #startTethering(int, OnStartTetheringCallback, boolean)
+     * @hide
+     */
+    @SystemApi
+    public static final int TETHERING_WIFI      = 0;
+
+    /**
+     * USB tethering type.
+     * @see #startTethering(int, OnStartTetheringCallback, boolean)
+     * @hide
+     */
+    @SystemApi
+    public static final int TETHERING_USB       = 1;
+
+    /**
+     * Bluetooth tethering type.
+     * @see #startTethering(int, OnStartTetheringCallback, boolean)
+     * @hide
+     */
+    @SystemApi
+    public static final int TETHERING_BLUETOOTH = 2;
+
+    /**
+     * Extra used for communicating with the TetherService. Includes the type of tethering to
+     * enable if any.
+     * @hide
+     */
+    public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
+
+    /**
+     * Extra used for communicating with the TetherService. Includes the type of tethering for
+     * which to cancel provisioning.
+     * @hide
+     */
+    public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
+
+    /**
+     * Extra used for communicating with the TetherService. True to schedule a recheck of tether
+     * provisioning.
+     * @hide
+     */
+    public static final String EXTRA_SET_ALARM = "extraSetAlarm";
+
+    /**
+     * Tells the TetherService to run a provision check now.
+     * @hide
+     */
+    public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
+
+    /**
+     * Extra used for communicating with the TetherService. Contains the {@link ResultReceiver}
+     * which will receive provisioning results. Can be left empty.
+     * @hide
+     */
+    public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
+
+    /**
      * The absence of a connection type.
      * @hide
      */
@@ -1543,7 +1611,7 @@
         if (b != null) {
             try {
                 ITelephony it = ITelephony.Stub.asInterface(b);
-                int subId = SubscriptionManager.getDefaultDataSubId();
+                int subId = SubscriptionManager.getDefaultDataSubscriptionId();
                 Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
                 boolean retVal = it.getDataEnabled(subId);
                 Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
@@ -1789,6 +1857,11 @@
      * or the ability to modify system settings as determined by
      * {@link android.provider.Settings.System#canWrite}.</p>
      *
+     * <p>WARNING: New clients should not use this function. The only usages should be in PanService
+     * and WifiStateMachine which need direct access. All other clients should use
+     * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
+     * logic.</p>
+     *
      * @param iface the interface name to tether.
      * @return error a {@code TETHER_ERROR} value indicating success or failure type
      *
@@ -1810,6 +1883,11 @@
      * or the ability to modify system settings as determined by
      * {@link android.provider.Settings.System#canWrite}.</p>
      *
+     * <p>WARNING: New clients should not use this function. The only usages should be in PanService
+     * and WifiStateMachine which need direct access. All other clients should use
+     * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
+     * logic.</p>
+     *
      * @param iface the interface name to untether.
      * @return error a {@code TETHER_ERROR} value indicating success or failure type
      *
@@ -1834,6 +1912,7 @@
      *
      * {@hide}
      */
+    @SystemApi
     public boolean isTetheringSupported() {
         try {
             return mService.isTetheringSupported();
@@ -1843,6 +1922,94 @@
     }
 
     /**
+     * Callback for use with {@link #startTethering} to find out whether tethering succeeded.
+     * @hide
+     */
+    @SystemApi
+    public static abstract class OnStartTetheringCallback {
+        /**
+         * Called when tethering has been successfully started.
+         */
+        public void onTetheringStarted() {};
+
+        /**
+         * Called when starting tethering failed.
+         */
+        public void onTetheringFailed() {};
+    }
+
+    /**
+     * Convenient overload for
+     * {@link #startTethering(int, boolean, OnStartTetheringCallback, Handler)} which passes a null
+     * handler to run on the current thread's {@link Looper}.
+     * @hide
+     */
+    @SystemApi
+    public void startTethering(int type, boolean showProvisioningUi,
+            final OnStartTetheringCallback callback) {
+        startTethering(type, showProvisioningUi, callback, null);
+    }
+
+    /**
+     * Runs tether provisioning for the given type if needed and then starts tethering if
+     * the check succeeds. If no carrier provisioning is required for tethering, tethering is
+     * enabled immediately. If provisioning fails, tethering will not be enabled. It also
+     * schedules tether provisioning re-checks if appropriate.
+     *
+     * @param type The type of tethering to start. Must be one of
+     *         {@link ConnectivityManager.TETHERING_WIFI},
+     *         {@link ConnectivityManager.TETHERING_USB}, or
+     *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
+     * @param showProvisioningUi a boolean indicating to show the provisioning app UI if there
+     *         is one. This should be true the first time this function is called and also any time
+     *         the user can see this UI. It gives users information from their carrier about the
+     *         check failing and how they can sign up for tethering if possible.
+     * @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller
+     *         of the result of trying to tether.
+     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
+     * @hide
+     */
+    @SystemApi
+    public void startTethering(int type, boolean showProvisioningUi,
+            final OnStartTetheringCallback callback, Handler handler) {
+        ResultReceiver wrappedCallback = new ResultReceiver(handler) {
+            @Override
+            protected void onReceiveResult(int resultCode, Bundle resultData) {
+                if (resultCode == TETHER_ERROR_NO_ERROR) {
+                    callback.onTetheringStarted();
+                } else {
+                    callback.onTetheringFailed();
+                }
+            }
+        };
+        try {
+            mService.startTethering(type, wrappedCallback, showProvisioningUi);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception trying to start tethering.", e);
+            wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
+        }
+    }
+
+    /**
+     * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if
+     * applicable.
+     *
+     * @param type The type of tethering to stop. Must be one of
+     *         {@link ConnectivityManager.TETHERING_WIFI},
+     *         {@link ConnectivityManager.TETHERING_USB}, or
+     *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
+     * @hide
+     */
+    @SystemApi
+    public void stopTethering(int type) {
+        try {
+            mService.stopTethering(type);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception trying to stop tethering.", e);
+        }
+    }
+
+    /**
      * Get the list of regular expressions that define any tetherable
      * USB network interfaces.  If USB tethering is not supported by the
      * device, this list should be empty.
@@ -1949,6 +2116,8 @@
     public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
     /** {@hide} */
     public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
+    /** {@hide} */
+    public static final int TETHER_ERROR_PROVISION_FAILED     = 11;
 
     /**
      * Get a more detailed error code after a Tethering or Untethering
@@ -3051,12 +3220,13 @@
      */
     public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
     @IntDef(flag = false, value = {
             RESTRICT_BACKGROUND_STATUS_DISABLED,
             RESTRICT_BACKGROUND_STATUS_WHITELISTED,
             RESTRICT_BACKGROUND_STATUS_ENABLED,
     })
-    @Retention(RetentionPolicy.SOURCE)
     public @interface RestrictBackgroundStatus {
     }
 
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 569468e..1a9c9ea 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -76,6 +76,10 @@
 
     boolean isTetheringSupported();
 
+    void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi);
+
+    void stopTethering(int type);
+
     String[] getTetherableIfaces();
 
     String[] getTetheredIfaces();
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 961a3f4..940565f 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -26,6 +26,7 @@
 import android.nfc.INfcAdapterExtras;
 import android.nfc.INfcTag;
 import android.nfc.INfcCardEmulation;
+import android.nfc.INfcFCardEmulation;
 import android.nfc.INfcUnlockHandler;
 import android.os.Bundle;
 
@@ -36,6 +37,7 @@
 {
     INfcTag getNfcTagInterface();
     INfcCardEmulation getNfcCardEmulationInterface();
+    INfcFCardEmulation getNfcFCardEmulationInterface();
     INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
 
     int getState();
diff --git a/core/java/android/nfc/INfcFCardEmulation.aidl b/core/java/android/nfc/INfcFCardEmulation.aidl
new file mode 100644
index 0000000..124bfac
--- /dev/null
+++ b/core/java/android/nfc/INfcFCardEmulation.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import android.content.ComponentName;
+import android.nfc.cardemulation.NfcFServiceInfo;
+
+/**
+ * @hide
+ */
+interface INfcFCardEmulation
+{
+    String getSystemCodeForService(int userHandle, in ComponentName service);
+    boolean registerSystemCodeForService(int userHandle, in ComponentName service, String systemCode);
+    boolean removeSystemCodeForService(int userHandle, in ComponentName service);
+    String getNfcid2ForService(int userHandle, in ComponentName service);
+    boolean setNfcid2ForService(int userHandle, in ComponentName service, String nfcid2);
+    boolean enableNfcFForegroundService(in ComponentName service);
+    boolean disableNfcFForegroundService();
+    List<NfcFServiceInfo> getNfcFServices(int userHandle);
+    int getMaxNumOfRegisterableSystemCodes();
+}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index ff6eb40..acd780d 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -294,6 +294,7 @@
     static INfcAdapter sService;
     static INfcTag sTagService;
     static INfcCardEmulation sCardEmulationService;
+    static INfcFCardEmulation sNfcFCardEmulationService;
 
     /**
      * The NfcAdapter object for each application context.
@@ -452,6 +453,13 @@
                 throw new UnsupportedOperationException();
             }
 
+            try {
+                sNfcFCardEmulationService = sService.getNfcFCardEmulationInterface();
+            } catch (RemoteException e) {
+                Log.e(TAG, "could not retrieve NFC-F card emulation service");
+                throw new UnsupportedOperationException();
+            }
+
             sIsInitialized = true;
         }
         if (context == null) {
@@ -571,6 +579,15 @@
     }
 
     /**
+     * Returns the binder interface to the NFC-F card emulation service.
+     * @hide
+     */
+    public INfcFCardEmulation getNfcFCardEmulationService() {
+        isEnabled();
+        return sNfcFCardEmulationService;
+    }
+
+    /**
      * NFC service dead - attempt best effort recovery
      * @hide
      */
@@ -601,6 +618,12 @@
             Log.e(TAG, "could not retrieve NFC card emulation service during service recovery");
         }
 
+        try {
+            sNfcFCardEmulationService = service.getNfcFCardEmulationInterface();
+        } catch (RemoteException ee) {
+            Log.e(TAG, "could not retrieve NFC-F card emulation service during service recovery");
+        }
+
         return;
     }
 
diff --git a/core/java/android/nfc/cardemulation/HostNfcFService.java b/core/java/android/nfc/cardemulation/HostNfcFService.java
new file mode 100644
index 0000000..273ddeb
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/HostNfcFService.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.cardemulation;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * <p>HostNfcFService is a convenience {@link Service} class that can be
+ * extended to emulate an NFC-F card inside an Android service component.
+ */
+public abstract class HostNfcFService extends Service {
+    /**
+     * The {@link Intent} action that must be declared as handled by the service.
+     */
+    @SdkConstant(SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
+
+    /**
+     * The name of the meta-data element that contains
+     * more information about this service.
+     */
+    public static final String SERVICE_META_DATA =
+            "android.nfc.cardemulation.host_nfcf_service";
+
+    /**
+     * Reason for {@link #onDeactivated(int)}.
+     * Indicates deactivation was due to the NFC link
+     * being lost.
+     */
+    public static final int DEACTIVATION_LINK_LOSS = 0;
+
+    static final String TAG = "NfcFService";
+
+    /**
+     * MSG_COMMAND_PACKET is sent by NfcService when
+     * a NFC-F command packet has been received.
+     *
+     * @hide
+     */
+    public static final int MSG_COMMAND_PACKET = 0;
+
+    /**
+     * MSG_RESPONSE_PACKET is sent to NfcService to send
+     * a response packet back to the remote device.
+     *
+     * @hide
+     */
+    public static final int MSG_RESPONSE_PACKET = 1;
+
+    /**
+     * MSG_DEACTIVATED is sent by NfcService when
+     * the current session is finished; because
+     * the NFC link was deactivated.
+     *
+     * @hide
+     */
+    public static final int MSG_DEACTIVATED = 2;
+
+   /**
+     * @hide
+     */
+    public static final String KEY_DATA = "data";
+
+    /**
+     * @hide
+     */
+    public static final String KEY_MESSENGER = "messenger";
+
+    /**
+     * Messenger interface to NfcService for sending responses.
+     * Only accessed on main thread by the message handler.
+     *
+     * @hide
+     */
+    Messenger mNfcService = null;
+
+    final Messenger mMessenger = new Messenger(new MsgHandler());
+
+    final class MsgHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case MSG_COMMAND_PACKET:
+                Bundle dataBundle = msg.getData();
+                if (dataBundle == null) {
+                    return;
+                }
+                if (mNfcService == null) mNfcService = msg.replyTo;
+
+                byte[] packet = dataBundle.getByteArray(KEY_DATA);
+                if (packet != null) {
+                    byte[] responsePacket = processNfcFPacket(packet, null);
+                    if (responsePacket != null) {
+                        if (mNfcService == null) {
+                            Log.e(TAG, "Response not sent; service was deactivated.");
+                            return;
+                        }
+                        Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
+                        Bundle responseBundle = new Bundle();
+                        responseBundle.putByteArray(KEY_DATA, responsePacket);
+                        responseMsg.setData(responseBundle);
+                        responseMsg.replyTo = mMessenger;
+                        try {
+                            mNfcService.send(responseMsg);
+                        } catch (RemoteException e) {
+                            Log.e("TAG", "Response not sent; RemoteException calling into " +
+                                    "NfcService.");
+                        }
+                    }
+                } else {
+                    Log.e(TAG, "Received MSG_COMMAND_PACKET without data.");
+                }
+                break;
+            case MSG_RESPONSE_PACKET:
+                if (mNfcService == null) {
+                    Log.e(TAG, "Response not sent; service was deactivated.");
+                    return;
+                }
+                try {
+                    msg.replyTo = mMessenger;
+                    mNfcService.send(msg);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException calling into NfcService.");
+                }
+                break;
+            case MSG_DEACTIVATED:
+                // Make sure we won't call into NfcService again
+                mNfcService = null;
+                onDeactivated(msg.arg1);
+                break;
+            default:
+                super.handleMessage(msg);
+            }
+        }
+    }
+
+    @Override
+    public final IBinder onBind(Intent intent) {
+        return mMessenger.getBinder();
+    }
+
+    /**
+     * Sends a response packet back to the remote device.
+     *
+     * <p>Note: this method may be called from any thread and will not block.
+     * @param responsePacket A byte-array containing the response packet.
+     */
+    public final void sendResponsePacket(byte[] responsePacket) {
+        Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
+        Bundle dataBundle = new Bundle();
+        dataBundle.putByteArray(KEY_DATA, responsePacket);
+        responseMsg.setData(dataBundle);
+        try {
+            mMessenger.send(responseMsg);
+        } catch (RemoteException e) {
+            Log.e("TAG", "Local messenger has died.");
+        }
+    }
+
+    /**
+     * <p>This method will be called when a NFC-F packet has been received
+     * from a remote device. A response packet can be provided directly
+     * by returning a byte-array in this method. Note that in general
+     * response packets must be sent as quickly as possible, given the fact
+     * that the user is likely holding his device over an NFC reader
+     * when this method is called.
+     *
+     * <p class="note">This method is running on the main thread of your application.
+     * If you cannot return a response packet immediately, return null
+     * and use the {@link #sendResponsePacket(byte[])} method later.
+     *
+     * @param commandPacket The NFC-F packet that was received from the remote device
+     * @param extras A bundle containing extra data. May be null.
+     * @return a byte-array containing the response packet, or null if no
+     *         response packet can be sent at this point.
+     */
+    public abstract byte[] processNfcFPacket(byte[] commandPacket, Bundle extras);
+
+    /**
+     * This method will be called in following possible scenarios:
+     * <li>The NFC link has been lost
+     * @param reason {@link #DEACTIVATION_LINK_LOSS}
+     */
+    public abstract void onDeactivated(int reason);
+}
diff --git a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
new file mode 100644
index 0000000..d61ac02
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
@@ -0,0 +1,470 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.cardemulation;
+
+import android.app.Activity;
+import android.app.ActivityThread;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.nfc.INfcFCardEmulation;
+import android.nfc.NfcAdapter;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * This class can be used to query the state of
+ * NFC-F card emulation services.
+ *
+ * For a general introduction into NFC card emulation,
+ * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
+ * NFC card emulation developer guide</a>.</p>
+ *
+ * <p class="note">Use of this class requires the
+ * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION_NFCF}
+ * to be present on the device.
+ */
+public final class NfcFCardEmulation {
+    static final String TAG = "NfcFCardEmulation";
+
+    static boolean sIsInitialized = false;
+    static HashMap<Context, NfcFCardEmulation> sCardEmus = new HashMap<Context, NfcFCardEmulation>();
+    static INfcFCardEmulation sService;
+
+    final Context mContext;
+
+    private NfcFCardEmulation(Context context, INfcFCardEmulation service) {
+        mContext = context.getApplicationContext();
+        sService = service;
+    }
+
+    /**
+     * Helper to get an instance of this class.
+     *
+     * @param adapter A reference to an NfcAdapter object.
+     * @return
+     */
+    public static synchronized NfcFCardEmulation getInstance(NfcAdapter adapter) {
+        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
+        Context context = adapter.getContext();
+        if (context == null) {
+            Log.e(TAG, "NfcAdapter context is null.");
+            throw new UnsupportedOperationException();
+        }
+        if (!sIsInitialized) {
+            IPackageManager pm = ActivityThread.getPackageManager();
+            if (pm == null) {
+                Log.e(TAG, "Cannot get PackageManager");
+                throw new UnsupportedOperationException();
+            }
+            try {
+                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
+                    Log.e(TAG, "This device does not support NFC-F card emulation");
+                    throw new UnsupportedOperationException();
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "PackageManager query failed.");
+                throw new UnsupportedOperationException();
+            }
+            sIsInitialized = true;
+        }
+        NfcFCardEmulation manager = sCardEmus.get(context);
+        if (manager == null) {
+            // Get card emu service
+            INfcFCardEmulation service = adapter.getNfcFCardEmulationService();
+            if (service == null) {
+                Log.e(TAG, "This device does not implement the INfcFCardEmulation interface.");
+                throw new UnsupportedOperationException();
+            }
+            manager = new NfcFCardEmulation(context, service);
+            sCardEmus.put(context, manager);
+        }
+        return manager;
+    }
+
+    /**
+     * Retrieves the current System Code for the specified service.
+     *
+     * <p>Before calling {@link #registerSystemCodeForService(ComponentName, String)},
+     * the System Code contained in the Manifest file is returned. After calling
+     * {@link #registerSystemCodeForService(ComponentName, String)}, the System Code
+     * registered there is returned. After calling
+     * {@link #removeSystemCodeForService(ComponentName)}, "null" is returned.
+     *
+     * @param service The component name of the service
+     * @return the current System Code
+     */
+    public String getSystemCodeForService(ComponentName service) {
+        if (service == null) {
+            throw new NullPointerException("service is null");
+        }
+        try {
+            return sService.getSystemCodeForService(UserHandle.myUserId(), service);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return null;
+            }
+            try {
+                return sService.getSystemCodeForService(UserHandle.myUserId(), service);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Registers a System Code for the specified service.
+     *
+     * <p>The System Code must be in range from "4000" to "4FFF" (excluding "4*FF").
+     *
+     * <p>If a System Code was previously registered for this service
+     * (either statically through the manifest, or dynamically by using this API),
+     * it will be replaced with this one.
+     *
+     * <p>Even if the same System Code is already registered for another service,
+     * this method succeeds in registering the System Code.
+     *
+     * <p>Note that you can only register a System Code for a service that
+     * is running under the same UID as the caller of this API. Typically
+     * this means you need to call this from the same
+     * package as the service itself, though UIDs can also
+     * be shared between packages using shared UIDs.
+     *
+     * @param service The component name of the service
+     * @param systemCode The System Code to be registered
+     * @return whether the registration was successful.
+     */
+    public boolean registerSystemCodeForService(ComponentName service, String systemCode) {
+        if (service == null || systemCode == null) {
+            throw new NullPointerException("service or systemCode is null");
+        }
+        try {
+            return sService.registerSystemCodeForService(UserHandle.myUserId(),
+                    service, systemCode);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+            try {
+                return sService.registerSystemCodeForService(UserHandle.myUserId(),
+                        service, systemCode);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Removes a registered System Code for the specified service.
+     *
+     * @param service The component name of the service
+     * @return whether the System Code was successfully removed.
+     */
+    public boolean removeSystemCodeForService(ComponentName service) {
+        if (service == null) {
+            throw new NullPointerException("service is null");
+        }
+        try {
+            return sService.removeSystemCodeForService(UserHandle.myUserId(), service);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+            try {
+                return sService.removeSystemCodeForService(UserHandle.myUserId(), service);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Retrieves the current NFCID2 for the specified service.
+     *
+     * <p>Before calling {@link #setNfcid2ForService(ComponentName, String)},
+     * the NFCID2 contained in the Manifest file is returned. If "random" is specified
+     * in the Manifest file, a random number assigned by the system at installation time
+     * is returned. After setting an NFCID2
+     * with {@link #setNfcid2ForService(ComponentName, String)}, this NFCID2 is returned.
+     *
+     * @param service The component name of the service
+     * @return the current NFCID2
+     */
+    public String getNfcid2ForService(ComponentName service) {
+        if (service == null) {
+            throw new NullPointerException("service is null");
+        }
+        try {
+            return sService.getNfcid2ForService(UserHandle.myUserId(), service);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return null;
+            }
+            try {
+                return sService.getNfcid2ForService(UserHandle.myUserId(), service);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Set a NFCID2 for the specified service.
+     *
+     * <p>The NFCID2 must be in range from "02FE000000000000" to "02FEFFFFFFFFFFFF".
+     *
+     * <p>If a NFCID2 was previously set for this service
+     * (either statically through the manifest, or dynamically by using this API),
+     * it will be replaced.
+     *
+     * <p>Note that you can only set the NFCID2 for a service that
+     * is running under the same UID as the caller of this API. Typically
+     * this means you need to call this from the same
+     * package as the service itself, though UIDs can also
+     * be shared between packages using shared UIDs.
+     *
+     * @param service The component name of the service
+     * @param nfcid2 The NFCID2 to be registered
+     * @return whether the setting was successful.
+     */
+    public boolean setNfcid2ForService(ComponentName service, String nfcid2) {
+        if (service == null || nfcid2 == null) {
+            throw new NullPointerException("service or nfcid2 is null");
+        }
+        try {
+            return sService.setNfcid2ForService(UserHandle.myUserId(),
+                    service, nfcid2);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+            try {
+                return sService.setNfcid2ForService(UserHandle.myUserId(),
+                        service, nfcid2);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Allows a foreground application to specify which card emulation service
+     * should be enabled while a specific Activity is in the foreground.
+     *
+     * <p>The specified HCE-F service is only enabled when the corresponding application is
+     * in the foreground and this method has been called. When the application is moved to
+     * the background, {@link #disableNfcFForegroundService(Activity)} is called, or
+     * NFCID2 or System Code is replaced, the HCE-F service is disabled.
+     *
+     * <p>The specified Activity must currently be in resumed state. A good
+     * paradigm is to call this method in your {@link Activity#onResume}, and to call
+     * {@link #disableNfcFForegroundService(Activity)} in your {@link Activity#onPause}.
+     *
+     * <p>Note that this preference is not persisted by the OS, and hence must be
+     * called every time the Activity is resumed.
+     *
+     * @param activity The activity which prefers this service to be invoked
+     * @param service The service to be preferred while this activity is in the foreground
+     * @return whether the registration was successful
+     */
+    public boolean enableNfcFForegroundService(Activity activity, ComponentName service) {
+        if (activity == null || service == null) {
+            throw new NullPointerException("activity or service is null");
+        }
+        // Verify the activity is in the foreground before calling into NfcService
+        if (!activity.isResumed()) {
+            throw new IllegalArgumentException("Activity must be resumed.");
+        }
+        try {
+            return sService.enableNfcFForegroundService(service);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+            try {
+                return sService.enableNfcFForegroundService(service);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Disables the service for the specified Activity.
+     *
+     * <p>Note that the specified Activity must still be in resumed
+     * state at the time of this call. A good place to call this method
+     * is in your {@link Activity#onPause} implementation.
+     *
+     * @param activity The activity which the service was registered for
+     * @return true when successful
+     */
+    public boolean disableNfcFForegroundService(Activity activity) {
+        if (activity == null) {
+            throw new NullPointerException("activity is null");
+        }
+        if (!activity.isResumed()) {
+            throw new IllegalArgumentException("Activity must be resumed.");
+        }
+        try {
+            return sService.disableNfcFForegroundService();
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+            try {
+                return sService.disableNfcFForegroundService();
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public List<NfcFServiceInfo> getNfcFServices() {
+        try {
+            return sService.getNfcFServices(UserHandle.myUserId());
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return null;
+            }
+            try {
+                return sService.getNfcFServices(UserHandle.myUserId());
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return null;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public int getMaxNumOfRegisterableSystemCodes() {
+        try {
+            return sService.getMaxNumOfRegisterableSystemCodes();
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return -1;
+            }
+            try {
+                return sService.getMaxNumOfRegisterableSystemCodes();
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return -1;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static boolean isValidSystemCode(String systemCode) {
+        if (systemCode == null) {
+            return false;
+        }
+        if (systemCode.length() != 4) {
+            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
+            return false;
+        }
+        // check if the value is between "4000" and "4FFF" (excluding "4*FF")
+        if (!systemCode.startsWith("4") || systemCode.toUpperCase().endsWith("FF")) {
+            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
+            return false;
+        }
+        try {
+            Integer.valueOf(systemCode, 16);
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @hide
+     */
+    public static boolean isValidNfcid2(String nfcid2) {
+        if (nfcid2 == null) {
+            return false;
+        }
+        if (nfcid2.length() != 16) {
+            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
+            return false;
+        }
+        // check if the the value starts with "02FE"
+        if (!nfcid2.toUpperCase().startsWith("02FE")) {
+            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
+            return false;
+        }
+        try {
+            Long.valueOf(nfcid2, 16);
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
+            return false;
+        }
+        return true;
+    }
+
+    void recoverService() {
+        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
+        sService = adapter.getNfcFCardEmulationService();
+    }
+
+}
+
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl b/core/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
similarity index 74%
rename from wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl
rename to core/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
index 27f23bc..56b98eb 100644
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl
+++ b/core/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
+/*
+ * Copyright (C) 2015 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.passpoint;
+package android.nfc.cardemulation;
 
-parcelable WifiPasspointInfo;
+parcelable NfcFServiceInfo;
diff --git a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
new file mode 100644
index 0000000..b93eec1
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.cardemulation;
+
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @hide
+ */
+public final class NfcFServiceInfo implements Parcelable {
+    static final String TAG = "NfcFServiceInfo";
+
+    /**
+     * The service that implements this
+     */
+    final ResolveInfo mService;
+
+    /**
+     * Description of the service
+     */
+    final String mDescription;
+
+    /**
+     * System Code of the service
+     */
+    final String mSystemCode;
+
+    /**
+     * System Code of the service registered by API
+     */
+    String mDynamicSystemCode;
+
+    /**
+     * NFCID2 of the service
+     */
+    final String mNfcid2;
+
+    /**
+     * NFCID2 of the service registered by API
+     */
+    String mDynamicNfcid2;
+
+    /**
+     * The uid of the package the service belongs to
+     */
+    final int mUid;
+
+    /**
+     * @hide
+     */
+    public NfcFServiceInfo(ResolveInfo info, String description,
+            String systemCode, String dynamicSystemCode, String nfcid2, String dynamicNfcid2,
+            int uid) {
+        this.mService = info;
+        this.mDescription = description;
+        this.mSystemCode = systemCode;
+        this.mDynamicSystemCode = dynamicSystemCode;
+        this.mNfcid2 = nfcid2;
+        this.mDynamicNfcid2 = dynamicNfcid2;
+        this.mUid = uid;
+    }
+
+    public NfcFServiceInfo(PackageManager pm, ResolveInfo info)
+            throws XmlPullParserException, IOException {
+        ServiceInfo si = info.serviceInfo;
+        XmlResourceParser parser = null;
+        try {
+            parser = si.loadXmlMetaData(pm, HostNfcFService.SERVICE_META_DATA);
+            if (parser == null) {
+                throw new XmlPullParserException("No " + HostNfcFService.SERVICE_META_DATA +
+                        " meta-data");
+            }
+
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.START_TAG &&
+                    eventType != XmlPullParser.END_DOCUMENT) {
+                eventType = parser.next();
+            }
+
+            String tagName = parser.getName();
+            if (!"host-nfcf-service".equals(tagName)) {
+                throw new XmlPullParserException(
+                        "Meta-data does not start with <host-nfcf-service> tag");
+            }
+
+            Resources res = pm.getResourcesForApplication(si.applicationInfo);
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+            TypedArray sa = res.obtainAttributes(attrs,
+                    com.android.internal.R.styleable.HostNfcFService);
+            mService = info;
+            mDescription = sa.getString(
+                    com.android.internal.R.styleable.HostNfcFService_description);
+            mDynamicSystemCode = null;
+            mDynamicNfcid2 = null;
+            sa.recycle();
+
+            String systemCode = null;
+            String nfcid2 = null;
+            final int depth = parser.getDepth();
+
+            while (((eventType = parser.next()) != XmlPullParser.END_TAG ||
+                    parser.getDepth() > depth) && eventType != XmlPullParser.END_DOCUMENT) {
+                tagName = parser.getName();
+                if (eventType == XmlPullParser.START_TAG &&
+                        "system-code-filter".equals(tagName) && systemCode == null) {
+                    final TypedArray a = res.obtainAttributes(attrs,
+                            com.android.internal.R.styleable.SystemCodeFilter);
+                    systemCode = a.getString(
+                            com.android.internal.R.styleable.SystemCodeFilter_name).toUpperCase();
+                    if (!NfcFCardEmulation.isValidSystemCode(systemCode) &&
+                            !systemCode.equalsIgnoreCase("NULL")) {
+                        Log.e(TAG, "Invalid System Code: " + systemCode);
+                        systemCode = null;
+                    }
+                    a.recycle();
+                } else if (eventType == XmlPullParser.START_TAG &&
+                        "nfcid2-filter".equals(tagName) && nfcid2 == null) {
+                    final TypedArray a = res.obtainAttributes(attrs,
+                            com.android.internal.R.styleable.Nfcid2Filter);
+                    nfcid2 = a.getString(
+                            com.android.internal.R.styleable.Nfcid2Filter_name).toUpperCase();
+                    if (!nfcid2.equalsIgnoreCase("RANDOM") &&
+                            !nfcid2.equalsIgnoreCase("NULL") &&
+                            !NfcFCardEmulation.isValidNfcid2(nfcid2)) {
+                        Log.e(TAG, "Invalid NFCID2: " + nfcid2);
+                        nfcid2 = null;
+                    }
+                    a.recycle();
+                }
+            }
+            mSystemCode = (systemCode == null ? "NULL" : systemCode);
+            mNfcid2 = (nfcid2 == null ? "NULL" : nfcid2);
+        } catch (NameNotFoundException e) {
+            throw new XmlPullParserException("Unable to create context for: " + si.packageName);
+        } finally {
+            if (parser != null) parser.close();
+        }
+        // Set uid
+        mUid = si.applicationInfo.uid;
+    }
+
+    public ComponentName getComponent() {
+        return new ComponentName(mService.serviceInfo.packageName,
+                mService.serviceInfo.name);
+    }
+
+    public String getSystemCode() {
+        return (mDynamicSystemCode == null ? mSystemCode : mDynamicSystemCode);
+    }
+
+    public void setOrReplaceDynamicSystemCode(String systemCode) {
+        mDynamicSystemCode = systemCode;
+    }
+
+    public String getNfcid2() {
+        return (mDynamicNfcid2 == null ? mNfcid2 : mDynamicNfcid2);
+    }
+
+    public void setOrReplaceDynamicNfcid2(String nfcid2) {
+        mDynamicNfcid2 = nfcid2;
+    }
+
+    public String getDescription() {
+        return mDescription;
+    }
+
+    public int getUid() {
+        return mUid;
+    }
+
+    public CharSequence loadLabel(PackageManager pm) {
+        return mService.loadLabel(pm);
+    }
+
+    public Drawable loadIcon(PackageManager pm) {
+        return mService.loadIcon(pm);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder out = new StringBuilder("NfcFService: ");
+        out.append(getComponent());
+        out.append(", description: " + mDescription);
+        out.append(", System Code: " + mSystemCode);
+        if (mDynamicSystemCode != null) {
+            out.append(", dynamic System Code: " + mDynamicSystemCode);
+        }
+        out.append(", NFCID2: " + mNfcid2);
+        if (mDynamicNfcid2 != null) {
+            out.append(", dynamic NFCID2: " + mDynamicNfcid2);
+        }
+        return out.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof NfcFServiceInfo)) return false;
+        NfcFServiceInfo thatService = (NfcFServiceInfo) o;
+
+        if (!thatService.getComponent().equals(this.getComponent())) return false;
+        if (!thatService.mSystemCode.equalsIgnoreCase(this.mSystemCode)) return false;
+        if (!thatService.mNfcid2.equalsIgnoreCase(this.mNfcid2)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return getComponent().hashCode();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        mService.writeToParcel(dest, flags);
+        dest.writeString(mDescription);
+        dest.writeString(mSystemCode);
+        dest.writeInt(mDynamicSystemCode != null ? 1 : 0);
+        if (mDynamicSystemCode != null) {
+            dest.writeString(mDynamicSystemCode);
+        }
+        dest.writeString(mNfcid2);
+        dest.writeInt(mDynamicNfcid2 != null ? 1 : 0);
+        if (mDynamicNfcid2 != null) {
+            dest.writeString(mDynamicNfcid2);
+        }
+        dest.writeInt(mUid);
+    };
+
+    public static final Parcelable.Creator<NfcFServiceInfo> CREATOR =
+            new Parcelable.Creator<NfcFServiceInfo>() {
+        @Override
+        public NfcFServiceInfo createFromParcel(Parcel source) {
+            ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source);
+            String description = source.readString();
+            String systemCode = source.readString();
+            String dynamicSystemCode = null;
+            if (source.readInt() != 0) {
+                dynamicSystemCode = source.readString();
+            }
+            String nfcid2 = source.readString();
+            String dynamicNfcid2 = null;
+            if (source.readInt() != 0) {
+                dynamicNfcid2 = source.readString();
+            }
+            int uid = source.readInt();
+            NfcFServiceInfo service = new NfcFServiceInfo(info, description,
+                    systemCode, dynamicSystemCode, nfcid2, dynamicNfcid2, uid);
+            return service;
+        }
+
+        @Override
+        public NfcFServiceInfo[] newArray(int size) {
+            return new NfcFServiceInfo[size];
+        }
+    };
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("    " + getComponent() +
+                " (Description: " + getDescription() + ")");
+        pw.println("    System Code: " + getSystemCode());
+        pw.println("    NFCID2: " + getNfcid2());
+    }
+}
+
diff --git a/core/java/android/os/CpuUsageInfo.java b/core/java/android/os/CpuUsageInfo.java
new file mode 100644
index 0000000..54caa15
--- /dev/null
+++ b/core/java/android/os/CpuUsageInfo.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/**
+ * CPU usage information per core.
+ */
+public final class CpuUsageInfo implements Parcelable {
+    private long mActive;
+    private long mTotal;
+
+    public static final Parcelable.Creator<CpuUsageInfo> CREATOR = new
+            Parcelable.Creator<CpuUsageInfo>() {
+                    public CpuUsageInfo createFromParcel(Parcel in) {
+                        return new CpuUsageInfo(in);
+                    }
+
+                    public CpuUsageInfo[] newArray(int size) {
+                        return new CpuUsageInfo[size];
+                    }
+                };
+
+    /** @hide */
+    public CpuUsageInfo(long activeTime, long totalTime) {
+        mActive = activeTime;
+        mTotal = totalTime;
+    }
+
+    private CpuUsageInfo(Parcel in) {
+        readFromParcel(in);
+    }
+
+    /**
+     * Gets the active time in milliseconds since the system last booted.
+     *
+     * @return Active time in milliseconds.
+     */
+    public long getActive() {
+        return mActive;
+    }
+
+    /**
+     * Gets the total time in milliseconds that the CPU has been enabled since the system last
+     * booted. This includes time the CPU spent idle.
+     *
+     * @return Total time in milliseconds.
+     */
+    public long getTotal() {
+        return mTotal;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeLong(mActive);
+        out.writeLong(mTotal);
+    }
+
+    private void readFromParcel(Parcel in) {
+        mActive = in.readLong();
+        mTotal = in.readLong();
+    }
+}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index ba215bb..c776ef8 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -402,7 +402,7 @@
      * type.
      */
     public static String DIRECTORY_PODCASTS = "Podcasts";
-    
+
     /**
      * Standard directory in which to place any audio files that should be
      * in the list of ringtones that the user can select (not as regular
@@ -414,7 +414,7 @@
      * type.
      */
     public static String DIRECTORY_RINGTONES = "Ringtones";
-    
+
     /**
      * Standard directory in which to place any audio files that should be
      * in the list of alarms that the user can select (not as regular
@@ -426,7 +426,7 @@
      * type.
      */
     public static String DIRECTORY_ALARMS = "Alarms";
-    
+
     /**
      * Standard directory in which to place any audio files that should be
      * in the list of notifications that the user can select (not as regular
@@ -438,7 +438,7 @@
      * type.
      */
     public static String DIRECTORY_NOTIFICATIONS = "Notifications";
-    
+
     /**
      * Standard directory in which to place pictures that are available to
      * the user.  Note that this is primarily a convention for the top-level
@@ -446,7 +446,7 @@
      * in any directory.
      */
     public static String DIRECTORY_PICTURES = "Pictures";
-    
+
     /**
      * Standard directory in which to place movies that are available to
      * the user.  Note that this is primarily a convention for the top-level
@@ -454,7 +454,7 @@
      * in any directory.
      */
     public static String DIRECTORY_MOVIES = "Movies";
-    
+
     /**
      * Standard directory in which to place files that have been downloaded by
      * the user.  Note that this is primarily a convention for the top-level
@@ -464,7 +464,7 @@
      * backwards compatibility reasons.
      */
     public static String DIRECTORY_DOWNLOADS = "Download";
-    
+
     /**
      * The traditional location for pictures and videos when mounting the
      * device as a camera.  Note that this is primarily a convention for the
@@ -496,7 +496,7 @@
      * </ul>
      * @hide
      */
-    public static final String[] STANDARD_DIRECTORIES = {
+    private static final String[] STANDARD_DIRECTORIES = {
             DIRECTORY_MUSIC,
             DIRECTORY_PODCASTS,
             DIRECTORY_RINGTONES,
@@ -510,6 +510,18 @@
     };
 
     /**
+     * @hide
+     */
+    public static boolean isStandardDirectory(String dir) {
+        for (String valid : STANDARD_DIRECTORIES) {
+            if (valid.equals(dir)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Get a top-level shared/external storage directory for placing files of a
      * particular type. This is where the user will typically place and manage
      * their own files, so you should be careful about what you put here to
@@ -559,7 +571,7 @@
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAppDataDirs(packageName);
     }
-    
+
     /**
      * Generates the raw path to an application's media
      * @hide
@@ -568,7 +580,7 @@
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAppMediaDirs(packageName);
     }
-    
+
     /**
      * Generates the raw path to an application's OBB files
      * @hide
@@ -577,7 +589,7 @@
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAppObbDirs(packageName);
     }
-    
+
     /**
      * Generates the path to an application's files.
      * @hide
@@ -595,7 +607,7 @@
         throwIfUserRequired();
         return sCurrentUser.buildExternalStorageAppCacheDirs(packageName);
     }
-    
+
     /**
      * Return the download/cache content directory.
      */
diff --git a/core/java/android/os/HardwarePropertiesManager.java b/core/java/android/os/HardwarePropertiesManager.java
new file mode 100644
index 0000000..bc317b6
--- /dev/null
+++ b/core/java/android/os/HardwarePropertiesManager.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.os;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+/**
+ * The HardwarePropertiesManager class provides a mechanism of accessing hardware state of a
+ * device: CPU, GPU and battery temperatures, CPU usage per core, fan speed, etc.
+ */
+public class HardwarePropertiesManager {
+
+    private static final String TAG = HardwarePropertiesManager.class.getSimpleName();
+
+    private static native void nativeInit();
+
+    private static native float[] nativeGetFanSpeeds();
+    private static native float[] nativeGetDeviceTemperatures(int type);
+    private static native CpuUsageInfo[] nativeGetCpuUsages();
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        DEVICE_TEMPERATURE_CPU, DEVICE_TEMPERATURE_GPU, DEVICE_TEMPERATURE_BATTERY
+    })
+    public @interface DeviceTemperatureType {}
+
+    /**
+     * Device temperature types. These must match the values in
+     * frameworks/native/include/hardwareproperties/HardwarePropertiesManager.h
+     */
+    /** Temperature of CPUs in Celsius. */
+    public static final int DEVICE_TEMPERATURE_CPU = 0;
+
+    /** Temperature of GPUs in Celsius. */
+    public static final int DEVICE_TEMPERATURE_GPU = 1;
+
+    /** Temperature of battery in Celsius. */
+    public static final int DEVICE_TEMPERATURE_BATTERY = 2;
+
+    /** @hide */
+    public HardwarePropertiesManager() {
+        nativeInit();
+    }
+
+    /**
+     * Return an array of device temperatures in Celsius.
+     *
+     * @param type type of requested device temperature, one of {@link #DEVICE_TEMPERATURE_CPU},
+     * {@link #DEVICE_TEMPERATURE_GPU} or {@link #DEVICE_TEMPERATURE_BATTERY}.
+     * @return an array of requested float device temperatures.
+     *         Empty if platform doesn't provide the queried temperature.
+     *
+     * @throws IllegalArgumentException if an incorrect temperature type is queried.
+    */
+    public @NonNull float[] getDeviceTemperatures(@DeviceTemperatureType int type) {
+        switch (type) {
+        case DEVICE_TEMPERATURE_CPU:
+        case DEVICE_TEMPERATURE_GPU:
+        case DEVICE_TEMPERATURE_BATTERY:
+            return nativeGetDeviceTemperatures(type);
+        default:
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /**
+     * Return an array of CPU usage info for each core.
+     *
+     * @return an array of {@link android.os.CpuUsageInfo} for each core.
+     *         Empty if CPU usage is not supported on this system.
+     */
+    public @NonNull CpuUsageInfo[] getCpuUsages() {
+        return nativeGetCpuUsages();
+    }
+
+    /**
+     * Return an array of fan speeds in RPM.
+     *
+     * @return an arrat of float fan speeds. Empty if there is no fans or fan speed
+     *         not supported on this system.
+     */
+    public @NonNull float[] getFanSpeeds() {
+        return nativeGetFanSpeeds();
+    }
+}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 4159d89..314b7d5 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -219,6 +219,15 @@
     public static final int DRAW_WAKE_LOCK = 0x00000080;
 
     /**
+     * Wake lock level: Enables Sustained Performance Mode.
+     * <p>
+     * This is used by Gaming and VR applications to ensure the device provides
+     * will provide consistent performance over a large amount of time.
+     * </p>
+     */
+    public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 0x00000100;
+
+    /**
      * Mask for the wake lock level component of a combined wake lock level and flags integer.
      *
      * @hide
@@ -525,6 +534,7 @@
             case PROXIMITY_SCREEN_OFF_WAKE_LOCK:
             case DOZE_WAKE_LOCK:
             case DRAW_WAKE_LOCK:
+            case SUSTAINED_PERFORMANCE_WAKE_LOCK:
                 break;
             default:
                 throw new IllegalArgumentException("Must specify a valid wake lock level.");
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index f765336..58a0269 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -91,4 +91,19 @@
      * the icon is in this method.
      */
     public abstract void setUserIcon(int userId, Bitmap bitmap);
+
+    /**
+     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to inform the
+     * user manager whether all users should be created ephemeral.
+     */
+    public abstract void setForceEphemeralUsers(boolean forceEphemeralUsers);
+
+    /**
+     * Switches to the system user and deletes all other users.
+     *
+     * <p>Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when
+     * the force-ephemeral-users policy is toggled on to make sure there are no pre-existing
+     * non-ephemeral users left.
+     */
+    public abstract void removeAllUsers();
 }
diff --git a/core/java/android/print/PrintJob.java b/core/java/android/print/PrintJob.java
index 777baab..66181e0 100644
--- a/core/java/android/print/PrintJob.java
+++ b/core/java/android/print/PrintJob.java
@@ -19,6 +19,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 
+import java.util.Objects;
+
 /**
  * This class represents a print job from the perspective of an
  * application. It contains behavior methods for performing operations
@@ -30,11 +32,11 @@
  */
 public final class PrintJob {
 
-    private final PrintManager mPrintManager;
+    private final @NonNull PrintManager mPrintManager;
 
-    private PrintJobInfo mCachedInfo;
+    private @NonNull PrintJobInfo mCachedInfo;
 
-    PrintJob(PrintJobInfo info, PrintManager printManager) {
+    PrintJob(@NonNull PrintJobInfo info, @NonNull PrintManager printManager) {
         mCachedInfo = info;
         mPrintManager = printManager;
     }
@@ -44,7 +46,7 @@
      *
      * @return The id.
      */
-    public @NonNull PrintJobId getId() {
+    public @Nullable PrintJobId getId() {
         return mCachedInfo.getId();
     }
 
@@ -58,7 +60,7 @@
      *
      * @return The print job info.
      */
-    public @Nullable PrintJobInfo getInfo() {
+    public @NonNull PrintJobInfo getInfo() {
         if (isInImmutableState()) {
             return mCachedInfo;
         }
@@ -193,11 +195,17 @@
             return false;
         }
         PrintJob other = (PrintJob) obj;
-        return mCachedInfo.getId().equals(other.mCachedInfo.getId());
+        return Objects.equals(mCachedInfo.getId(), other.mCachedInfo.getId());
     }
 
     @Override
     public int hashCode() {
-        return mCachedInfo.getId().hashCode();
+        PrintJobId printJobId = mCachedInfo.getId();
+
+        if (printJobId == null) {
+            return 0;
+        } else {
+            return printJobId.hashCode();
+        }
     }
 }
diff --git a/core/java/android/print/PrintJobId.java b/core/java/android/print/PrintJobId.java
index a2ee02b..186ae9b 100644
--- a/core/java/android/print/PrintJobId.java
+++ b/core/java/android/print/PrintJobId.java
@@ -19,7 +19,8 @@
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
 
 import java.util.UUID;
 
@@ -27,7 +28,7 @@
  * This class represents the id of a print job.
  */
 public final class PrintJobId implements Parcelable {
-    private final String mValue;
+    private final @NonNull String mValue;
 
     /**
      * Creates a new instance.
@@ -45,7 +46,7 @@
      *
      * @hide
      */
-    public PrintJobId(String value) {
+    public PrintJobId(@NonNull String value) {
         mValue = value;
     }
 
@@ -53,7 +54,7 @@
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = prime * result + ((mValue != null) ? mValue.hashCode() : 0);
+        result = prime * result + mValue.hashCode();
         return result;
     }
 
@@ -69,7 +70,7 @@
             return false;
         }
         PrintJobId other = (PrintJobId) obj;
-        if (!TextUtils.equals(mValue, other.mValue)) {
+        if (!mValue.equals(other.mValue)) {
             return false;
         }
         return true;
@@ -104,7 +105,7 @@
      *
      * @hide
      */
-    public static PrintJobId unflattenFromString(String string) {
+    public static @NonNull PrintJobId unflattenFromString(@NonNull String string) {
         return new PrintJobId(string);
     }
 
@@ -112,7 +113,7 @@
             new Parcelable.Creator<PrintJobId>() {
         @Override
         public PrintJobId createFromParcel(Parcel parcel) {
-            return new PrintJobId(parcel.readString());
+            return new PrintJobId(Preconditions.checkNotNull(parcel.readString()));
         }
 
         @Override
diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java
index 21836b3..7e3a72f 100644
--- a/core/java/android/print/PrintJobInfo.java
+++ b/core/java/android/print/PrintJobInfo.java
@@ -244,7 +244,7 @@
      *
      * @return The id.
      */
-    public @NonNull PrintJobId getId() {
+    public @Nullable PrintJobId getId() {
         return mId;
     }
 
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index 3eb4874..58f260c 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -535,7 +535,10 @@
         return new PrinterDiscoverySession(mService, mContext, mUserId);
     }
 
-    private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub
+    /**
+     * @hide
+     */
+    public static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub
             implements ActivityLifecycleCallbacks {
         private final Object mLock = new Object();
 
@@ -1061,7 +1064,10 @@
         }
     }
 
-    private static final class PrintJobStateChangeListenerWrapper extends
+    /**
+     * @hide
+     */
+    public static final class PrintJobStateChangeListenerWrapper extends
             IPrintJobStateChangeListener.Stub {
         private final WeakReference<PrintJobStateChangeListener> mWeakListener;
         private final WeakReference<Handler> mWeakHandler;
diff --git a/core/java/android/print/PrinterDiscoverySession.java b/core/java/android/print/PrinterDiscoverySession.java
index abb441b..c587edd 100644
--- a/core/java/android/print/PrinterDiscoverySession.java
+++ b/core/java/android/print/PrinterDiscoverySession.java
@@ -16,6 +16,8 @@
 
 package android.print;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.ParceledListSlice;
 import android.os.Handler;
@@ -72,7 +74,7 @@
         }
     }
 
-    public final void startPrinterDiscovery(List<PrinterId> priorityList) {
+    public final void startPrinterDiscovery(@Nullable List<PrinterId> priorityList) {
         if (isDestroyed()) {
             Log.w(LOG_TAG, "Ignoring start printers discovery - session destroyed");
             return;
@@ -102,7 +104,7 @@
         }
     }
 
-    public final void startPrinterStateTracking(PrinterId printerId) {
+    public final void startPrinterStateTracking(@NonNull PrinterId printerId) {
         if (isDestroyed()) {
             Log.w(LOG_TAG, "Ignoring start printer state tracking - session destroyed");
             return;
@@ -114,7 +116,7 @@
         }
     }
 
-    public final void stopPrinterStateTracking(PrinterId printerId) {
+    public final void stopPrinterStateTracking(@NonNull PrinterId printerId) {
         if (isDestroyed()) {
             Log.w(LOG_TAG, "Ignoring stop printer state tracking - session destroyed");
             return;
@@ -285,7 +287,7 @@
         }
     }
 
-    private static final class PrinterDiscoveryObserver extends IPrinterDiscoveryObserver.Stub {
+    public static final class PrinterDiscoveryObserver extends IPrinterDiscoveryObserver.Stub {
 
         private final WeakReference<PrinterDiscoverySession> mWeakSession;
 
diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
index 3104492..62d214e 100644
--- a/core/java/android/printservice/PrintService.java
+++ b/core/java/android/printservice/PrintService.java
@@ -16,6 +16,7 @@
 
 package android.printservice;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Service;
 import android.content.ComponentName;
@@ -346,7 +347,7 @@
      * @param localId A locally unique id in the context of your print service.
      * @return Global printer id.
      */
-    public final PrinterId generatePrinterId(String localId) {
+    public @NonNull final PrinterId generatePrinterId(String localId) {
         throwIfNotCalledOnMainThread();
         localId = Preconditions.checkNotNull(localId, "localId cannot be null");
         return new PrinterId(new ComponentName(getPackageName(),
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b547432..330fcf6 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -8401,10 +8401,15 @@
          * @hide
          */
         public static Intent rebuildManagedQuickContactsIntent(String lookupKey, long contactId,
-                long directoryId, Intent originalIntent) {
+                boolean isContactIdIgnored, long directoryId, Intent originalIntent) {
             final Intent intent = new Intent(ACTION_QUICK_CONTACT);
             // Rebuild the URI from a lookup key and a contact ID.
-            Uri uri = Contacts.getLookupUri(contactId, lookupKey);
+            Uri uri = null;
+            if (!TextUtils.isEmpty(lookupKey)) {
+                uri = isContactIdIgnored
+                        ? Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey)
+                        : Contacts.getLookupUri(contactId, lookupKey);
+            }
             if (uri != null && directoryId != Directory.DEFAULT) {
                 uri = uri.buildUpon().appendQueryParameter(
                         ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)).build();
@@ -8699,6 +8704,120 @@
                 "com.android.contacts.action.SHOW_OR_CREATE_CONTACT";
 
         /**
+         * Activity Action: Initiate a message to someone by voice. The message could be text,
+         * audio, video or image(photo). This action supports messaging with a specific contact
+         * regardless of the underlying messaging protocol used.
+         * <p>
+         * The action could be originated from the Voice Assistant as a voice interaction. In such
+         * case, a receiving activity that supports {@link android.content.Intent#CATEGORY_VOICE}
+         * could check return value of {@link android.app.Activity#isVoiceInteractionRoot} before
+         * proceeding. By doing this check the activity verifies that the action indeed was
+         * initiated by Voice Assistant and could send a message right away, without any further
+         * input from the user. This allows for a smooth user experience when sending a message by
+         * voice. Note: this activity must also support the {@link
+         * android.content.Intent#CATEGORY_DEFAULT} so it can be found by {@link
+         * android.service.voice.VoiceInteractionSession#startVoiceActivity}.
+         * <p>
+         * When the action was not initiated by Voice Assistant or when the receiving activity does
+         * not support {@link android.content.Intent#CATEGORY_VOICE}, the activity should confirm
+         * with the user before sending the message (because in this case it is unknown which app
+         * sent the intent, it could be malicious).
+         * <p>
+         * To allow the Voice Assistant to help users with contacts disambiguation, the messaging
+         * app may choose to integrate with the Contacts Provider. The following convention should
+         * be met when creating Data table for such integration:
+         * <ul>
+         * <li>Column {@link DataColumns#DATA1} should store the unique contact ID as understood by
+         * the app. This value will be used in the {@link #EXTRA_RECIPIENT_CONTACT_CHAT_ID}.</li>
+         * <li>Optionally, column {@link DataColumns#DATA3} could store a human readable label for
+         * the ID. For example it could be phone number or human readable username/user_id like
+         * "a_super_cool_user_name". This label may be shown below the Contact Name by the Voice
+         * Assistant as the user completes the voice action. If DATA3 is empty, the ID in DATA1 may
+         * be shown instead.</li>
+         * <li><em>Note: Do not use DATA3 to store the Contact Name. The Voice Assistant will
+         * already get the Contact Name from the RawContact’s display_name.</em></li>
+         * <li><em>Note: Some apps may choose to use phone number as the unique contact ID in DATA1.
+         * If this applies to you and you’d like phone number to be shown below the Contact Name by
+         * the Voice Assistant, then you may choose to leave DATA3 empty.</em></li>
+         * </ul>
+         * <p>
+         * Input: {@link android.content.Intent#getType} is the MIME type of the data being sent.
+         * The intent sender will always put the concrete mime type in the intent type, like
+         * "text/plain" or "audio/wav" for example. If the MIME type is "text/plain", message to
+         * sent will be provided via {@link android.content.Intent#EXTRA_TEXT} as a styled
+         * CharSequence. Otherwise, the message content will be supplied through {@link
+         * android.content.Intent#setClipData(ClipData)} as a content provider URI(s). In the latter
+         * case, EXTRA_TEXT could still be supplied optionally; for example, for audio messages
+         * ClipData will contain URI of a recording and EXTRA_TEXT could contain the text
+         * transcription of this recording.
+         * <p>
+         * The message can have n recipients. The n-th recipient of the message will be provided as
+         * n-th elements of {@link #EXTRA_RECIPIENT_CONTACT_URI}, {@link
+         * #EXTRA_RECIPIENT_CONTACT_CHAT_ID} and {@link #EXTRA_RECIPIENT_CONTACT_NAME} (as a
+         * consequence, EXTRA_RECIPIENT_CONTACT_URI, EXTRA_RECIPIENT_CONTACT_CHAT_ID and
+         * EXTRA_RECIPIENT_CONTACT_NAME should all be of length n). If neither of these 3 elements
+         * is provided (e.g. all 3 are null) for the recipient or if the information provided is
+         * ambiguous then the activity should prompt the user for the recipient to send the message
+         * to.
+         * <p>
+         * Output: nothing
+         *
+         * @see #EXTRA_RECIPIENT_CONTACT_URI
+         * @see #EXTRA_RECIPIENT_CONTACT_CHAT_ID
+         * @see #EXTRA_RECIPIENT_CONTACT_NAME
+         */
+        public static final String ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS =
+                "android.provider.action.VOICE_SEND_MESSAGE_TO_CONTACTS";
+
+        /**
+         * This extra specifies a content provider uri(s) for the contact(s) (if the contacts were
+         * located in the Contacts Provider), used with {@link
+         * #ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS} to supply the recipient(s). The value of this
+         * extra is a {@code String[]}. The number of elements in the array should be equal to
+         * number of recipients (and consistent with {@link #EXTRA_RECIPIENT_CONTACT_CHAT_ID} and
+         * {@link #EXTRA_RECIPIENT_CONTACT_NAME}). When the value of the element for the particular
+         * recipient is absent, it will be set to null.
+         * <p>
+         * <em>Note: one contact may have multiple accounts (e.g. Chat IDs) on a specific messaging
+         * platform, so this may be ambiguous. E.g., one contact “John Smith” could have two
+         * accounts on the same messaging app.</em>
+         * <p>
+         * <em>Example value: {"content://com.android.contacts/contacts/16"}</em>
+         */
+        public static final String EXTRA_RECIPIENT_CONTACT_URI =
+                "android.provider.extra.RECIPIENT_CONTACT_URI";
+
+        /**
+         * This extra specifies a messaging app’s unique ID(s) for the contact(s), used with {@link
+         * #ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS} to supply the recipient(s). The value of this
+         * extra is a {@code String[]}. The number of elements in the array should be equal to
+         * number of recipients (and consistent with {@link #EXTRA_RECIPIENT_CONTACT_URI} and {@link
+         * #EXTRA_RECIPIENT_CONTACT_NAME}). When the value of the element for the particular
+         * recipient is absent, it will be set to null.
+         * <p>
+         * The value of the elements comes from the {@link DataColumns#DATA1} column in Contacts
+         * Provider, and should be the unambiguous contact endpoint. This value is app-specific, it
+         * could be a phone number or some proprietary ID.
+         */
+        public static final String EXTRA_RECIPIENT_CONTACT_CHAT_ID =
+                "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
+
+        /**
+         * This extra specifies the contact name (full name from the Contacts Provider), used with
+         * {@link #ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS} to supply the recipient. The value of this
+         * extra is a {@code String[]}. The number of elements in the array should be equal to
+         * number of recipients (and consistent with {@link #EXTRA_RECIPIENT_CONTACT_URI} and {@link
+         * #EXTRA_RECIPIENT_CONTACT_CHAT_ID}). When the value of the element for the particular
+         * recipient is absent, it will be set to null.
+         * <p>
+         * The value of the elements comes from RawContact's display_name column.
+         * <p>
+         * <em>Example value: {"Jane Doe"}</em>
+         */
+        public static final String EXTRA_RECIPIENT_CONTACT_NAME =
+                "android.provider.extra.RECIPIENT_CONTACT_NAME";
+
+        /**
          * Starts an Activity that lets the user select the multiple phones from a
          * list of phone numbers which come from the contacts or
          * {@link #EXTRA_PHONE_URIS}.
diff --git a/core/java/android/provider/ContactsInternal.java b/core/java/android/provider/ContactsInternal.java
index 36ef52d..2cd1d48 100644
--- a/core/java/android/provider/ContactsInternal.java
+++ b/core/java/android/provider/ContactsInternal.java
@@ -42,10 +42,12 @@
     private static final UriMatcher sContactsUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 
     private static final int CONTACTS_URI_LOOKUP_ID = 1000;
+    private static final int CONTACTS_URI_LOOKUP = 1001;
 
     static {
         // Contacts URI matching table
         final UriMatcher matcher = sContactsUriMatcher;
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*", CONTACTS_URI_LOOKUP);
         matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*/#", CONTACTS_URI_LOOKUP_ID);
     }
 
@@ -57,6 +59,7 @@
 
         final int match = sContactsUriMatcher.match(uri);
         switch (match) {
+            case CONTACTS_URI_LOOKUP:
             case CONTACTS_URI_LOOKUP_ID: {
                 if (maybeStartManagedQuickContact(context, intent)) {
                     return; // Request handled by DPM.  Just return here.
@@ -89,7 +92,10 @@
 
         // Decompose into an ID and a lookup key.
         final List<String> pathSegments = uri.getPathSegments();
-        final long contactId = ContentUris.parseId(uri);
+        final boolean isContactIdIgnored = pathSegments.size() < 4;
+        final long contactId = isContactIdIgnored
+                ? ContactsContract.Contacts.ENTERPRISE_CONTACT_ID_BASE //contact id will be ignored
+                : ContentUris.parseId(uri);
         final String lookupKey = pathSegments.get(2);
         final String directoryIdStr = uri.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY);
         final long directoryId = (directoryIdStr == null)
@@ -119,8 +125,8 @@
         final long actualDirectoryId = (directoryId
                 - ContactsContract.Directory.ENTERPRISE_DIRECTORY_ID_BASE);
 
-        dpm.startManagedQuickContact(actualLookupKey, actualContactId, actualDirectoryId,
-                originalIntent);
+        dpm.startManagedQuickContact(actualLookupKey, actualContactId, isContactIdIgnored,
+                actualDirectoryId, originalIntent);
         return true;
     }
 }
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 88cc8a2..cdd88f6 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -342,8 +342,8 @@
          * within the same document provider.
          *
          * @see #COLUMN_FLAGS
-         * @see DocumentsContract#moveDocument(ContentProviderClient, Uri, Uri)
-         * @see DocumentsProvider#moveDocument(String, String)
+         * @see DocumentsContract#moveDocument(ContentProviderClient, Uri, Uri, Uri)
+         * @see DocumentsProvider#moveDocument(String, String, String)
          */
         public static final int FLAG_SUPPORTS_MOVE = 1 << 8;
 
@@ -614,6 +614,8 @@
     public static final String METHOD_IS_CHILD_DOCUMENT = "android:isChildDocument";
 
     /** {@hide} */
+    public static final String EXTRA_PARENT_URI = "parentUri";
+    /** {@hide} */
     public static final String EXTRA_URI = "uri";
 
     private static final String PATH_ROOT = "root";
@@ -1139,7 +1141,6 @@
      * @param targetParentDocumentUri document which will become a parent of the source
      *         document's copy.
      * @return the copied document, or {@code null} if failed.
-     * @hide
      */
     public static Uri copyDocument(ContentResolver resolver, Uri sourceDocumentUri,
             Uri targetParentDocumentUri) {
@@ -1170,17 +1171,18 @@
      * Moves the given document under a new parent.
      *
      * @param sourceDocumentUri document with {@link Document#FLAG_SUPPORTS_MOVE}
+     * @param sourceParentDocumentUri parent document of the document to move.
      * @param targetParentDocumentUri document which will become a new parent of the source
      *         document.
      * @return the moved document, or {@code null} if failed.
-     * @hide
      */
     public static Uri moveDocument(ContentResolver resolver, Uri sourceDocumentUri,
-            Uri targetParentDocumentUri) {
+            Uri sourceParentDocumentUri, Uri targetParentDocumentUri) {
         final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                 sourceDocumentUri.getAuthority());
         try {
-            return moveDocument(client, sourceDocumentUri, targetParentDocumentUri);
+            return moveDocument(client, sourceParentDocumentUri, sourceDocumentUri,
+                    targetParentDocumentUri);
         } catch (Exception e) {
             Log.w(TAG, "Failed to move document", e);
             return null;
@@ -1191,9 +1193,10 @@
 
     /** {@hide} */
     public static Uri moveDocument(ContentProviderClient client, Uri sourceDocumentUri,
-            Uri targetParentDocumentUri) throws RemoteException {
+            Uri sourceParentDocumentUri, Uri targetParentDocumentUri) throws RemoteException {
         final Bundle in = new Bundle();
         in.putParcelable(DocumentsContract.EXTRA_URI, sourceDocumentUri);
+        in.putParcelable(DocumentsContract.EXTRA_PARENT_URI, sourceParentDocumentUri);
         in.putParcelable(DocumentsContract.EXTRA_TARGET_URI, targetParentDocumentUri);
 
         final Bundle out = client.call(METHOD_MOVE_DOCUMENT, null, in);
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 94b4157..bae928d 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -289,12 +289,14 @@
      * be returned.
      *
      * @param sourceDocumentId the document to move.
+     * @param sourceParentDocumentId the parent of the document to move.
      * @param targetParentDocumentId the target document to be a new parent of the
      *     source document.
      * @hide
      */
     @SuppressWarnings("unused")
-    public String moveDocument(String sourceDocumentId, String targetParentDocumentId)
+    public String moveDocument(String sourceDocumentId, String sourceParentDocumentId,
+            String targetParentDocumentId)
             throws FileNotFoundException {
         throw new UnsupportedOperationException("Move not supported");
     }
@@ -759,7 +761,7 @@
 
                 out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);
 
-                // Original document no longer exists, clean up any grants
+                // Original document no longer exists, clean up any grants.
                 revokeDocumentPermission(documentId);
             }
 
@@ -767,7 +769,7 @@
             enforceWritePermissionInner(documentUri, getCallingPackage(), null);
             deleteDocument(documentId);
 
-            // Document no longer exists, clean up any grants
+            // Document no longer exists, clean up any grants.
             revokeDocumentPermission(documentId);
 
         } else if (METHOD_COPY_DOCUMENT.equals(method)) {
@@ -793,13 +795,16 @@
             }
 
         } else if (METHOD_MOVE_DOCUMENT.equals(method)) {
+            final Uri parentSourceUri = extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI);
+            final String parentSourceId = DocumentsContract.getDocumentId(parentSourceUri);
             final Uri targetUri = extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI);
             final String targetId = DocumentsContract.getDocumentId(targetUri);
 
-            enforceReadPermissionInner(documentUri, getCallingPackage(), null);
+            enforceWritePermissionInner(documentUri, getCallingPackage(), null);
+            enforceReadPermissionInner(parentSourceUri, getCallingPackage(), null);
             enforceWritePermissionInner(targetUri, getCallingPackage(), null);
 
-            final String newDocumentId = moveDocument(documentId, targetId);
+            final String newDocumentId = moveDocument(documentId, parentSourceId, targetId);
 
             if (newDocumentId != null) {
                 final Uri newDocumentUri = buildDocumentUriMaybeUsingTree(documentUri,
@@ -814,7 +819,7 @@
                 out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);
             }
 
-            // Original document no longer exists, clean up any grants
+            // Original document no longer exists, clean up any grants.
             revokeDocumentPermission(documentId);
 
         } else {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3042aa9..bc0d7d6 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -129,6 +129,27 @@
             "android.settings.WIRELESS_SETTINGS";
 
     /**
+     * Activity Action: Show tether provisioning activity.
+     *
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: {@link ConnectivityManager.EXTRA_TETHER_TYPE} should be included to specify which type
+     * of tethering should be checked. {@link ConnectivityManager.EXTRA_PROVISION_CALLBACK} should
+     * contain a {@link ResultReceiver} which will be called back with a tether result code.
+     * <p>
+     * Output: The result of the provisioning check.
+     * {@link ConnectivityManager.TETHER_ERROR_NO_ERROR} if successful,
+     * {@link ConnectivityManager.TETHER_ERROR_PROVISION_FAILED} for failure.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_TETHER_PROVISIONING =
+            "android.settings.TETHER_PROVISIONING_UI";
+
+    /**
      * Activity Action: Show settings to allow entering/exiting airplane mode.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -3278,6 +3299,7 @@
             WIFI_STATIC_DNS2,
             BLUETOOTH_DISCOVERABILITY,
             BLUETOOTH_DISCOVERABILITY_TIMEOUT,
+            FONT_SCALE,
             DIM_SCREEN,
             SCREEN_OFF_TIMEOUT,
             SCREEN_BRIGHTNESS,
@@ -5051,6 +5073,14 @@
         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
@@ -5862,6 +5892,7 @@
             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,
diff --git a/core/java/android/security/NetworkSecurityPolicy.java b/core/java/android/security/NetworkSecurityPolicy.java
index 37ec725..733a092 100644
--- a/core/java/android/security/NetworkSecurityPolicy.java
+++ b/core/java/android/security/NetworkSecurityPolicy.java
@@ -16,6 +16,11 @@
 
 package android.security;
 
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.security.net.config.ApplicationConfig;
+import android.security.net.config.ManifestConfigSource;
+
 /**
  * Network security policy.
  *
@@ -86,4 +91,17 @@
         FrameworkNetworkSecurityPolicy policy = new FrameworkNetworkSecurityPolicy(permitted);
         libcore.net.NetworkSecurityPolicy.setInstance(policy);
     }
+
+
+    /**
+     * Returns an {@link ApplicationConfig} based on the configuration for {@code packageName}.
+     *
+     * @hide
+     */
+    public static ApplicationConfig getApplicationConfigForPackage(Context context,
+            String packageName) throws PackageManager.NameNotFoundException {
+        Context appContext = context.createPackageContext(packageName, 0);
+        ManifestConfigSource source = new ManifestConfigSource(appContext);
+        return new ApplicationConfig(source);
+    }
 }
diff --git a/core/java/android/security/net/config/CertificateSource.java b/core/java/android/security/net/config/CertificateSource.java
index 7e3601e..f3272e4 100644
--- a/core/java/android/security/net/config/CertificateSource.java
+++ b/core/java/android/security/net/config/CertificateSource.java
@@ -16,12 +16,13 @@
 
 package android.security.net.config;
 
-import java.util.Set;
 import java.security.cert.X509Certificate;
+import java.util.Set;
 
 /** @hide */
 public interface CertificateSource {
     Set<X509Certificate> getCertificates();
     X509Certificate findBySubjectAndPublicKey(X509Certificate cert);
     X509Certificate findByIssuerAndSignature(X509Certificate cert);
+    Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert);
 }
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
index ff728ef..742d430 100644
--- a/core/java/android/security/net/config/CertificatesEntryRef.java
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -17,8 +17,8 @@
 package android.security.net.config;
 
 import android.util.ArraySet;
-import java.util.Set;
 import java.security.cert.X509Certificate;
+import java.util.Set;
 
 /** @hide */
 public final class CertificatesEntryRef {
@@ -60,4 +60,8 @@
 
         return new TrustAnchor(foundCert, mOverridesPins);
     }
+
+    public Set<X509Certificate> findAllCertificatesByIssuerAndSignature(X509Certificate cert) {
+        return mSource.findAllByIssuerAndSignature(cert);
+    }
 }
diff --git a/core/java/android/security/net/config/DirectoryCertificateSource.java b/core/java/android/security/net/config/DirectoryCertificateSource.java
index bf29efa..b2c068c 100644
--- a/core/java/android/security/net/config/DirectoryCertificateSource.java
+++ b/core/java/android/security/net/config/DirectoryCertificateSource.java
@@ -29,6 +29,7 @@
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.util.Collections;
 import java.util.Set;
 import libcore.io.IoUtils;
 
@@ -110,10 +111,50 @@
         });
     }
 
+    @Override
+    public Set<X509Certificate> findAllByIssuerAndSignature(final X509Certificate cert) {
+        return findCerts(cert.getIssuerX500Principal(), new CertSelector() {
+            @Override
+            public boolean match(X509Certificate ca) {
+                try {
+                    cert.verify(ca.getPublicKey());
+                    return true;
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+        });
+    }
+
     private static interface CertSelector {
         boolean match(X509Certificate cert);
     }
 
+    private Set<X509Certificate> findCerts(X500Principal subj, CertSelector selector) {
+        String hash = getHash(subj);
+        Set<X509Certificate> certs = null;
+        for (int index = 0; index >= 0; index++) {
+            String fileName = hash + "." + index;
+            if (!new File(mDir, fileName).exists()) {
+                break;
+            }
+            if (isCertMarkedAsRemoved(fileName)) {
+                continue;
+            }
+            X509Certificate cert = readCertificate(fileName);
+            if (!subj.equals(cert.getSubjectX500Principal())) {
+                continue;
+            }
+            if (selector.match(cert)) {
+                if (certs == null) {
+                    certs = new ArraySet<X509Certificate>();
+                }
+                certs.add(cert);
+            }
+        }
+        return certs != null ? certs : Collections.<X509Certificate>emptySet();
+    }
+
     private X509Certificate findCert(X500Principal subj, CertSelector selector) {
         String hash = getHash(subj);
         for (int index = 0; index >= 0; index++) {
diff --git a/core/java/android/security/net/config/KeyStoreCertificateSource.java b/core/java/android/security/net/config/KeyStoreCertificateSource.java
index b6105cd..ba5dd83 100644
--- a/core/java/android/security/net/config/KeyStoreCertificateSource.java
+++ b/core/java/android/security/net/config/KeyStoreCertificateSource.java
@@ -21,6 +21,7 @@
 import java.security.KeyStoreException;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.Set;
 
@@ -90,4 +91,18 @@
         }
         return anchor.getTrustedCert();
     }
+
+    @Override
+    public Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert) {
+        ensureInitialized();
+        Set<java.security.cert.TrustAnchor> anchors = mIndex.findAllByIssuerAndSignature(cert);
+        if (anchors.isEmpty()) {
+            return Collections.<X509Certificate>emptySet();
+        }
+        Set<X509Certificate> certs = new ArraySet<X509Certificate>(anchors.size());
+        for (java.security.cert.TrustAnchor anchor : anchors) {
+            certs.add(anchor.getTrustedCert());
+        }
+        return certs;
+    }
 }
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 0a2edff..ebe14691 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -145,6 +145,15 @@
         return null;
     }
 
+    /** @hide */
+    public Set<X509Certificate> findAllCertificatesByIssuerAndSignature(X509Certificate cert) {
+        Set<X509Certificate> certs = new ArraySet<X509Certificate>();
+        for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
+            certs.addAll(ref.findAllCertificatesByIssuerAndSignature(cert));
+        }
+        return certs;
+    }
+
     /**
      * Return a {@link Builder} for the default {@code NetworkSecurityConfig}.
      *
diff --git a/core/java/android/security/net/config/ResourceCertificateSource.java b/core/java/android/security/net/config/ResourceCertificateSource.java
index e489c2c..8803c4b 100644
--- a/core/java/android/security/net/config/ResourceCertificateSource.java
+++ b/core/java/android/security/net/config/ResourceCertificateSource.java
@@ -25,6 +25,7 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Set;
 
 import com.android.org.conscrypt.TrustedCertificateIndex;
@@ -100,4 +101,18 @@
         }
         return anchor.getTrustedCert();
     }
+
+    @Override
+    public Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert) {
+        ensureInitialized();
+        Set<java.security.cert.TrustAnchor> anchors = mIndex.findAllByIssuerAndSignature(cert);
+        if (anchors.isEmpty()) {
+            return Collections.<X509Certificate>emptySet();
+        }
+        Set<X509Certificate> certs = new ArraySet<X509Certificate>(anchors.size());
+        for (java.security.cert.TrustAnchor anchor : anchors) {
+            certs.add(anchor.getTrustedCert());
+        }
+        return certs;
+    }
 }
diff --git a/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java b/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
index 4a90f82..c2f29be 100644
--- a/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
+++ b/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
@@ -42,6 +42,11 @@
     }
 
     @Override
+    public Set<X509Certificate> findAllIssuers(X509Certificate cert) {
+        return mConfig.findAllCertificatesByIssuerAndSignature(cert);
+    }
+
+    @Override
     public X509Certificate getTrustAnchor(X509Certificate cert) {
         TrustAnchor anchor = mConfig.findTrustAnchorBySubjectAndPublicKey(cert);
         if (anchor == null) {
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 035462d..bd41fb5 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -98,6 +98,9 @@
     /** Notification was canceled by the user banning the topic. */
     public static final int REASON_TOPIC_BANNED = 14;
 
+    /** Notification was canceled by the device administrator suspending the package. */
+    public static final int REASON_PACKAGE_SUSPENDED = 15;
+
     public class Adjustment {
         int mImportance;
         CharSequence mExplanation;
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index ac7d539..76a401d 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -31,6 +31,7 @@
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
 import android.media.AudioFormat;
 import android.os.AsyncTask;
 import android.os.Handler;
@@ -616,7 +617,11 @@
         }
 
         @Override
-        public void onDetected(KeyphraseRecognitionEvent event) {
+        public void onDetected(RecognitionEvent event) {
+            if (! (event instanceof KeyphraseRecognitionEvent)) {
+                Slog.e(TAG, "onDetected() called for a soundtrigger event.");
+                return;
+            }
             if (DBG) {
                 Slog.d(TAG, "onDetected(" + event + ")");
             } else {
diff --git a/core/java/android/service/voice/VoiceInteractionManagerInternal.java b/core/java/android/service/voice/VoiceInteractionManagerInternal.java
new file mode 100644
index 0000000..b38067b
--- /dev/null
+++ b/core/java/android/service/voice/VoiceInteractionManagerInternal.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.service.voice;
+
+import android.os.Bundle;
+import android.os.IBinder;
+
+
+/**
+ * @hide
+ * Private interface to the VoiceInteractionManagerService for use by ActivityManagerService.
+ */
+public abstract class VoiceInteractionManagerInternal {
+
+    /**
+     * Start a new voice interaction session when requested from within an activity
+     * by Activity.startLocalVoiceInteraction()
+     * @param callingActivity The binder token representing the calling activity.
+     * @param options 
+     */
+    public abstract void startLocalVoiceInteraction(IBinder callingActivity, Bundle options);
+
+    /**
+     * Returns whether the currently selected voice interaction service supports local voice
+     * interaction for launching from an Activity.
+     */
+    public abstract boolean supportsLocalVoiceInteraction();
+
+    public abstract void stopLocalVoiceInteraction(IBinder callingActivity);
+}
\ No newline at end of file
diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
index ebe3f47..a9db32b 100644
--- a/core/java/android/service/voice/VoiceInteractionServiceInfo.java
+++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
@@ -45,6 +45,7 @@
     private String mSettingsActivity;
     private boolean mSupportsAssist;
     private boolean mSupportsLaunchFromKeyguard;
+    private boolean mSupportsLocalInteraction;
 
     public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp)
             throws PackageManager.NameNotFoundException {
@@ -70,6 +71,10 @@
     }
 
     public VoiceInteractionServiceInfo(PackageManager pm, ServiceInfo si) {
+        if (si == null) {
+            mParseError = "Service not available";
+            return;
+        }
         if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
             mParseError = "Service does not require permission "
                     + Manifest.permission.BIND_VOICE_INTERACTION;
@@ -114,6 +119,8 @@
             mSupportsLaunchFromKeyguard = array.getBoolean(com.android.internal.
                     R.styleable.VoiceInteractionService_supportsLaunchVoiceAssistFromKeyguard,
                     false);
+            mSupportsLocalInteraction = array.getBoolean(com.android.internal.
+                    R.styleable.VoiceInteractionService_supportsLocalInteraction, false);
             array.recycle();
             if (mSessionService == null) {
                 mParseError = "No sessionService specified";
@@ -168,4 +175,8 @@
     public boolean getSupportsLaunchFromKeyguard() {
         return mSupportsLaunchFromKeyguard;
     }
+
+    public boolean getSupportsLocalInteraction() {
+        return mSupportsLocalInteraction;
+    }
 }
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index ec14740..0c6a0c6 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -17,6 +17,7 @@
 package android.service.voice;
 
 import android.annotation.Nullable;
+import android.app.Activity;
 import android.app.Dialog;
 import android.app.Instrumentation;
 import android.app.VoiceInteractor;
@@ -49,6 +50,7 @@
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
+
 import com.android.internal.app.IVoiceInteractionManagerService;
 import com.android.internal.app.IVoiceInteractionSessionShowCallback;
 import com.android.internal.app.IVoiceInteractor;
@@ -75,7 +77,7 @@
  */
 public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCallbacks2 {
     static final String TAG = "VoiceInteractionSession";
-    static final boolean DEBUG = false;
+    static final boolean DEBUG = true;
 
     /**
      * Flag received in {@link #onShow}: originator requested that the session be started with
@@ -101,6 +103,13 @@
      */
     public static final int SHOW_SOURCE_APPLICATION = 1<<3;
 
+    /**
+     * Flag for use with {@link #onShow}: indicates that an Activity has invoked the voice
+     * interaction service for a local interaction using
+     * {@link Activity#startLocalVoiceInteraction(Bundle)}.
+     */
+    public static final int SHOW_SOURCE_ACTIVITY = 1<<4;
+
     final Context mContext;
     final HandlerCaller mHandlerCaller;
 
diff --git a/core/java/android/speech/tts/FileSynthesisCallback.java b/core/java/android/speech/tts/FileSynthesisCallback.java
index dea766b..ca9931a 100644
--- a/core/java/android/speech/tts/FileSynthesisCallback.java
+++ b/core/java/android/speech/tts/FileSynthesisCallback.java
@@ -111,6 +111,7 @@
                        "of AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT or " +
                        "AudioFormat.ENCODING_PCM_FLOAT");
         }
+        mDispatcher.dispatchOnBeginSynthesis(sampleRateInHz, audioFormat, channelCount);
 
         FileChannel fileChannel = null;
         synchronized (mStateLock) {
@@ -176,6 +177,10 @@
             fileChannel = mFileChannel;
         }
 
+        final byte[] bufferCopy = new byte[length];
+        System.arraycopy(buffer, offset, bufferCopy, 0, length);
+        mDispatcher.dispatchOnAudioAvailable(bufferCopy);
+
         try {
             fileChannel.write(ByteBuffer.wrap(buffer,  offset,  length));
             return TextToSpeech.SUCCESS;
diff --git a/core/java/android/speech/tts/ITextToSpeechCallback.aidl b/core/java/android/speech/tts/ITextToSpeechCallback.aidl
index d785c3f..4e3acf6 100644
--- a/core/java/android/speech/tts/ITextToSpeechCallback.aidl
+++ b/core/java/android/speech/tts/ITextToSpeechCallback.aidl
@@ -22,33 +22,65 @@
  */
 oneway interface ITextToSpeechCallback {
     /**
-     * Tells the client that the synthesis has started.
+     * Tells the client that the synthesis has started playing.
      *
-     * @param utteranceId Unique id identifying synthesis request.
+     * @param utteranceId Unique id identifying the synthesis request.
      */
     void onStart(String utteranceId);
 
     /**
-     * Tells the client that the synthesis has finished.
+     * Tells the client that the synthesis has finished playing.
      *
-     * @param utteranceId Unique id identifying synthesis request.
+     * @param utteranceId Unique id identifying the synthesis request.
      */
     void onSuccess(String utteranceId);
 
     /**
      * Tells the client that the synthesis was stopped.
      *
-     * @param utteranceId Unique id identifying synthesis request.
+     * @param utteranceId Unique id identifying the synthesis request.
      */
     void onStop(String utteranceId, boolean isStarted);
 
     /**
      * Tells the client that the synthesis has failed.
      *
-     * @param utteranceId Unique id identifying synthesis request.
+     * @param utteranceId Unique id identifying the synthesis request.
      * @param errorCode One of the values from
      *        {@link android.speech.tts.v2.TextToSpeech}.
      */
     void onError(String utteranceId, int errorCode);
 
+    /**
+     * Tells the client that the TTS engine has started synthesizing the audio for a request.
+     *
+     * <p>
+     * This doesn't mean the synthesis request has already started playing (for example when there
+     * are synthesis requests ahead of it in the queue), but after receiving this callback you can
+     * expect onAudioAvailable to be called.
+     * </p>
+     *
+     * @param utteranceId Unique id identifying the synthesis request.
+     * @param sampleRateInHz Sample rate in HZ of the generated audio.
+     * @param audioFormat The audio format of the generated audio in the {@link #onAudioAvailable}
+     *        call. Should be one of {@link android.media.AudioFormat.ENCODING_PCM_8BIT},
+     *        {@link android.media.AudioFormat.ENCODING_PCM_16BIT} or
+     *        {@link android.media.AudioFormat.ENCODING_PCM_FLOAT}.
+     * @param channelCount The number of channels.
+     */
+    void onBeginSynthesis(String utteranceId, int sampleRateInHz, int audioFormat, int channelCount);
+
+    /**
+     * Tells the client about a chunk of the synthesized audio.
+     *
+     * <p>
+     * Called when a chunk of the synthesized audio is ready. This may be called more than once for
+     * every synthesis request, thereby streaming the audio to the client.
+     * </p>
+     *
+     * @param utteranceId Unique id identifying the synthesis request.
+     * @param audio The raw audio bytes. Its format is specified by the {@link #onStartAudio}
+     * callback.
+     */
+    void onAudioAvailable(String utteranceId, in byte[] audio);
 }
diff --git a/core/java/android/speech/tts/PlaybackSynthesisCallback.java b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
index dcc0095..778aa86 100644
--- a/core/java/android/speech/tts/PlaybackSynthesisCallback.java
+++ b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
@@ -15,6 +15,7 @@
  */
 package android.speech.tts;
 
+import android.annotation.NonNull;
 import android.media.AudioFormat;
 import android.speech.tts.TextToSpeechService.AudioOutputParams;
 import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
@@ -51,9 +52,10 @@
     private final Object mCallerIdentity;
     private final AbstractEventLogger mLogger;
 
-    PlaybackSynthesisCallback(AudioOutputParams audioParams, AudioPlaybackHandler audioTrackHandler,
-            UtteranceProgressDispatcher dispatcher, Object callerIdentity,
-            AbstractEventLogger logger, boolean clientIsUsingV2) {
+    PlaybackSynthesisCallback(@NonNull AudioOutputParams audioParams,
+            @NonNull AudioPlaybackHandler audioTrackHandler,
+            @NonNull UtteranceProgressDispatcher dispatcher, @NonNull Object callerIdentity,
+            @NonNull AbstractEventLogger logger, boolean clientIsUsingV2) {
         super(clientIsUsingV2);
         mAudioParams = audioParams;
         mAudioTrackHandler = audioTrackHandler;
@@ -130,6 +132,7 @@
                        "of AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT or " +
                        "AudioFormat.ENCODING_PCM_FLOAT");
         }
+        mDispatcher.dispatchOnBeginSynthesis(sampleRateInHz, audioFormat, channelCount);
 
         int channelConfig = BlockingAudioTrack.getChannelConfig(channelCount);
 
@@ -190,6 +193,7 @@
         // Sigh, another copy.
         final byte[] bufferCopy = new byte[length];
         System.arraycopy(buffer, offset, bufferCopy, 0, length);
+        mDispatcher.dispatchOnAudioAvailable(bufferCopy);
 
         // Might block on mItem.this, if there are too many buffers waiting to
         // be consumed.
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 61c33ff..d55c7bd 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -16,6 +16,7 @@
 package android.speech.tts;
 
 import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.annotation.RawRes;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -665,7 +666,7 @@
     private OnInitListener mInitListener;
     // Written from an unspecified application thread, read from
     // a binder thread.
-    private volatile UtteranceProgressListener mUtteranceProgressListener;
+    @Nullable private volatile UtteranceProgressListener mUtteranceProgressListener;
     private final Object mStartLock = new Object();
 
     private String mRequestedEngine;
@@ -2133,6 +2134,23 @@
                     listener.onStart(utteranceId);
                 }
             }
+
+            @Override
+            public void onBeginSynthesis(String utteranceId, int sampleRateInHz, int audioFormat,
+                                     int channelCount) {
+                UtteranceProgressListener listener = mUtteranceProgressListener;
+                if (listener != null) {
+                    listener.onBeginSynthesis(utteranceId, sampleRateInHz, audioFormat, channelCount);
+                }
+            }
+
+            @Override
+            public void onAudioAvailable(String utteranceId, byte[] audio) {
+                UtteranceProgressListener listener = mUtteranceProgressListener;
+                if (listener != null) {
+                    listener.onAudioAvailable(utteranceId, audio);
+                }
+            }
         };
 
         private class SetupConnectionAsyncTask extends AsyncTask<Void, Void, Integer> {
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 8c355d8..fc075de 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -15,6 +15,7 @@
  */
 package android.speech.tts;
 
+import android.annotation.NonNull;
 import android.app.Service;
 import android.content.Intent;
 import android.media.AudioAttributes;
@@ -111,7 +112,7 @@
     // A thread and it's associated handler for playing back any audio
     // associated with this TTS engine. Will handle all requests except synthesis
     // to file requests, which occur on the synthesis thread.
-    private AudioPlaybackHandler mAudioPlaybackHandler;
+    @NonNull private AudioPlaybackHandler mAudioPlaybackHandler;
     private TtsEngines mEngineHelper;
 
     private CallbackMap mCallbacks;
@@ -649,6 +650,8 @@
         public void dispatchOnSuccess();
         public void dispatchOnStart();
         public void dispatchOnError(int errorCode);
+        public void dispatchOnBeginSynthesis(int sampleRateInHz, int audioFormat, int channelCount);
+        public void dispatchOnAudioAvailable(byte[] audio);
     }
 
     /** Set of parameters affecting audio output. */
@@ -853,6 +856,22 @@
             }
         }
 
+        @Override
+        public void dispatchOnBeginSynthesis(int sampleRateInHz, int audioFormat, int channelCount) {
+            final String utteranceId = getUtteranceId();
+            if (utteranceId != null) {
+                mCallbacks.dispatchOnBeginSynthesis(getCallerIdentity(), utteranceId, sampleRateInHz, audioFormat, channelCount);
+            }
+        }
+
+        @Override
+        public void dispatchOnAudioAvailable(byte[] audio) {
+            final String utteranceId = getUtteranceId();
+            if (utteranceId != null) {
+                mCallbacks.dispatchOnAudioAvailable(getCallerIdentity(), utteranceId, audio);
+            }
+        }
+
         abstract public String getUtteranceId();
 
         String getStringParam(Bundle params, String key, String defaultValue) {
@@ -1430,7 +1449,6 @@
             } catch (RemoteException e) {
                 Log.e(TAG, "Callback onStart failed: " + e);
             }
-
         }
 
         public void dispatchOnError(Object callerIdentity, String utteranceId,
@@ -1444,6 +1462,26 @@
             }
         }
 
+        public void dispatchOnBeginSynthesis(Object callerIdentity, String utteranceId, int sampleRateInHz, int audioFormat, int channelCount) {
+            ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
+            if (cb == null) return;
+            try {
+                cb.onBeginSynthesis(utteranceId, sampleRateInHz, audioFormat, channelCount);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Callback dispatchOnBeginSynthesis(String, int, int, int) failed: " + e);
+            }
+        }
+
+        public void dispatchOnAudioAvailable(Object callerIdentity, String utteranceId, byte[] buffer) {
+            ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
+            if (cb == null) return;
+            try {
+                cb.onAudioAvailable(utteranceId, buffer);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Callback dispatchOnAudioAvailable(String, byte[]) failed: " + e);
+            }
+        }
+
         @Override
         public void onCallbackDied(ITextToSpeechCallback callback, Object cookie) {
             IBinder caller = (IBinder) cookie;
diff --git a/core/java/android/speech/tts/UtteranceProgressListener.java b/core/java/android/speech/tts/UtteranceProgressListener.java
index 890ea3d..72a5228 100644
--- a/core/java/android/speech/tts/UtteranceProgressListener.java
+++ b/core/java/android/speech/tts/UtteranceProgressListener.java
@@ -2,6 +2,8 @@
 
 package android.speech.tts;
 
+import android.media.AudioFormat;
+
 /**
  * Listener for events relating to the progress of an utterance through
  * the synthesis queue. Each utterance is associated with a call to
@@ -14,10 +16,10 @@
     /**
      * Called when an utterance "starts" as perceived by the caller. This will
      * be soon before audio is played back in the case of a {@link TextToSpeech#speak}
-     * or before the first bytes of a file are written to storage in the case
+     * or before the first bytes of a file are written to the file system in the case
      * of {@link TextToSpeech#synthesizeToFile}.
      *
-     * @param utteranceId the utterance ID of the utterance.
+     * @param utteranceId The utterance ID of the utterance.
      */
     public abstract void onStart(String utteranceId);
 
@@ -28,7 +30,7 @@
      *
      * This request is guaranteed to be called after {@link #onStart(String)}.
      *
-     * @param utteranceId the utterance ID of the utterance.
+     * @param utteranceId The utterance ID of the utterance.
      */
     public abstract void onDone(String utteranceId);
 
@@ -39,7 +41,7 @@
      * be a call to both {@link #onDone(String)} and {@link #onError(String)} for
      * the same utterance.
      *
-     * @param utteranceId the utterance ID of the utterance.
+     * @param utteranceId The utterance ID of the utterance.
      * @deprecated Use {@link #onError(String,int)} instead
      */
     @Deprecated
@@ -52,7 +54,7 @@
      * be a call to both {@link #onDone(String)} and {@link #onError(String,int)} for
      * the same utterance. The default implementation calls {@link #onError(String)}.
      *
-     * @param utteranceId the utterance ID of the utterance.
+     * @param utteranceId The utterance ID of the utterance.
      * @param errorCode one of the ERROR_* codes from {@link TextToSpeech}
      */
     public void onError(String utteranceId, int errorCode) {
@@ -65,7 +67,7 @@
      * or uses {@link TextToSpeech#QUEUE_FLUSH} as an argument with the
      * {@link TextToSpeech#speak} or {@link TextToSpeech#synthesizeToFile} methods.
      *
-     * @param utteranceId the utterance ID of the utterance.
+     * @param utteranceId The utterance ID of the utterance.
      * @param interrupted If true, then the utterance was interrupted while being synthesized
      *        and its output is incomplete. If false, then the utterance was flushed
      *        before the synthesis started.
@@ -74,6 +76,52 @@
     }
 
     /**
+     * Called when the TTS engine begins to synthesize the audio for a request.
+     *
+     * <p>
+     * It provides information about the format of the byte array for subsequent
+     * {@link #onAudioAvailable} calls.
+     * </p>
+     *
+     * <p>
+     * This is called when the TTS engine starts synthesizing audio for the request. If an
+     * application wishes to know when the audio is about to start playing, {#onStart(String)}
+     * should be used instead.
+     * </p>
+     *
+     * @param utteranceId The utterance ID of the utterance.
+     * @param sampleRateInHz Sample rate in hertz of the generated audio.
+     * @param audioFormat Audio format of the generated audio. Should be one of
+     *        {@link AudioFormat#ENCODING_PCM_8BIT}, {@link AudioFormat#ENCODING_PCM_16BIT} or
+     *        {@link AudioFormat#ENCODING_PCM_FLOAT}.
+     * @param channelCount The number of channels.
+     */
+    public void onBeginSynthesis(String utteranceId, int sampleRateInHz, int audioFormat, int channelCount) {
+    }
+
+    /**
+     * This is called when a chunk of audio is ready for consumption.
+     *
+     * <p>
+     * The audio parameter is a copy of what will be synthesized to the speakers (when synthesis was
+     * initiated with a {@link TextToSpeech#speak} call) or written to the file system (for
+     * {@link TextToSpeech#synthesizeToFile}). The audio bytes are delivered in one or more chunks;
+     * if {@link #onDone} or {@link #onError} is called all chunks have been received.
+     * </p>
+     *
+     * <p>
+     * The audio received here may not be played for some time depending on buffer sizes and the
+     * amount of items on the synthesis queue.
+     * </p>
+     *
+     * @param utteranceId The utterance ID of the utterance.
+     * @param audio A chunk of audio; the format can be known by listening to
+     *        {@link #onBeginSynthesis(String, int, int, int)}.
+     */
+    public void onAudioAvailable(String utteranceId, byte[] audio) {
+    }
+
+    /**
      * Wraps an old deprecated OnUtteranceCompletedListener with a shiny new
      * progress listener.
      *
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index 3d8ab1e..ed91239c 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -16,7 +16,6 @@
 
 package android.text;
 
-import android.graphics.Color;
 import com.android.internal.util.ArrayUtils;
 import org.ccil.cowan.tagsoup.HTMLSchema;
 import org.ccil.cowan.tagsoup.Parser;
@@ -27,12 +26,17 @@
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
 
+import android.app.ActivityThread;
+import android.app.Application;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.text.style.AbsoluteSizeSpan;
 import android.text.style.AlignmentSpan;
+import android.text.style.BackgroundColorSpan;
+import android.text.style.BulletSpan;
 import android.text.style.CharacterStyle;
 import android.text.style.ForegroundColorSpan;
 import android.text.style.ImageSpan;
@@ -85,18 +89,109 @@
                                  Editable output, XMLReader xmlReader);
     }
 
+    /**
+     * Option for {@link #toHtml(Spanned, int)}: Wrap consecutive lines of text delimited by '\n'
+     * inside &lt;p&gt; elements. {@link BulletSpan}s are ignored.
+     */
+    public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0x00000000;
+
+    /**
+     * Option for {@link #toHtml(Spanned, int)}: Wrap each line of text delimited by '\n' inside a
+     * &lt;p&gt; or a &lt;li&gt; element. This allows {@link ParagraphStyle}s attached to be
+     * encoded as CSS styles within the corresponding &lt;p&gt; or &lt;li&gt; element.
+     */
+    public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 0x00000001;
+
+    /**
+     * Flag indicating that texts inside &lt;p&gt; elements will be separated from other texts with
+     * one newline character by default.
+     */
+    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 0x00000001;
+
+    /**
+     * Flag indicating that texts inside &lt;h1&gt;~&lt;h6&gt; elements will be separated from
+     * other texts with one newline character by default.
+     */
+    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 0x00000002;
+
+    /**
+     * Flag indicating that texts inside &lt;li&gt; elements will be separated from other texts
+     * with one newline character by default.
+     */
+    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 0x00000004;
+
+    /**
+     * Flag indicating that texts inside &lt;ul&gt; elements will be separated from other texts
+     * with one newline character by default.
+     */
+    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 0x00000008;
+
+    /**
+     * Flag indicating that texts inside &lt;div&gt; elements will be separated from other texts
+     * with one newline character by default.
+     */
+    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 0x00000010;
+
+    /**
+     * Flag indicating that texts inside &lt;blockquote&gt; elements will be separated from other
+     * texts with one newline character by default.
+     */
+    public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 0x00000020;
+
+    /**
+     * Flag indicating that CSS color values should be used instead of those defined in
+     * {@link Color}.
+     */
+    public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 0x00000100;
+
+    /**
+     * Flags for {@link #fromHtml(String, int, ImageGetter, TagHandler)}: Separate block-level
+     * elements with blank lines (two newline characters) in between. This is the legacy behavior
+     * prior to N.
+     */
+    public static final int FROM_HTML_MODE_LEGACY = 0x00000000;
+
+    /**
+     * Flags for {@link #fromHtml(String, int, ImageGetter, TagHandler)}: Separate block-level
+     * elements with line breaks (single newline character) in between. This inverts the
+     * {@link Spanned} to HTML string conversion done with the option
+     * {@link #TO_HTML_PARAGRAPH_LINES_INDIVIDUAL}.
+     */
+    public static final int FROM_HTML_MODE_COMPACT =
+            FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH
+            | FROM_HTML_SEPARATOR_LINE_BREAK_HEADING
+            | FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM
+            | FROM_HTML_SEPARATOR_LINE_BREAK_LIST
+            | FROM_HTML_SEPARATOR_LINE_BREAK_DIV
+            | FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE;
+
+    /**
+     * The bit which indicates if lines delimited by '\n' will be grouped into &lt;p&gt; elements.
+     */
+    private static final int TO_HTML_PARAGRAPH_FLAG = 0x00000001;
+
     private Html() { }
 
     /**
-     * Returns displayable styled text from the provided HTML string.
-     * Any &lt;img&gt; tags in the HTML will display as a generic
-     * replacement image which your program can then go through and
+     * Returns displayable styled text from the provided HTML string with the legacy flags
+     * {@link #FROM_HTML_MODE_LEGACY}.
+     *
+     * @deprecated use {@link #fromHtml(String, int)} instead.
+     */
+    @Deprecated
+    public static Spanned fromHtml(String source) {
+        return fromHtml(source, FROM_HTML_MODE_LEGACY, null, null);
+    }
+
+    /**
+     * Returns displayable styled text from the provided HTML string. Any &lt;img&gt; tags in the
+     * HTML will display as a generic replacement image which your program can then go through and
      * replace with real images.
      *
      * <p>This uses TagSoup to handle real HTML, including all of the brokenness found in the wild.
      */
-    public static Spanned fromHtml(String source) {
-        return fromHtml(source, null, null);
+    public static Spanned fromHtml(String source, int flags) {
+        return fromHtml(source, flags, null, null);
     }
 
     /**
@@ -109,16 +204,26 @@
     }
 
     /**
-     * Returns displayable styled text from the provided HTML string.
-     * Any &lt;img&gt; tags in the HTML will use the specified ImageGetter
-     * to request a representation of the image (use null if you don't
-     * want this) and the specified TagHandler to handle unknown tags
-     * (specify null if you don't want this).
+     * Returns displayable styled text from the provided HTML string with the legacy flags
+     * {@link #FROM_HTML_MODE_LEGACY}.
+     *
+     * @deprecated use {@link #fromHtml(String, int, ImageGetter, TagHandler)} instead.
+     */
+    @Deprecated
+    public static Spanned fromHtml(String source, ImageGetter imageGetter, TagHandler tagHandler) {
+        return fromHtml(source, FROM_HTML_MODE_LEGACY, imageGetter, tagHandler);
+    }
+
+    /**
+     * Returns displayable styled text from the provided HTML string. Any &lt;img&gt; tags in the
+     * HTML will use the specified ImageGetter to request a representation of the image (use null
+     * if you don't want this) and the specified TagHandler to handle unknown tags (specify null if
+     * you don't want this).
      *
      * <p>This uses TagSoup to handle real HTML, including all of the brokenness found in the wild.
      */
-    public static Spanned fromHtml(String source, ImageGetter imageGetter,
-                                   TagHandler tagHandler) {
+    public static Spanned fromHtml(String source, int flags, ImageGetter imageGetter,
+            TagHandler tagHandler) {
         Parser parser = new Parser();
         try {
             parser.setProperty(Parser.schemaProperty, HtmlParser.schema);
@@ -131,22 +236,31 @@
         }
 
         HtmlToSpannedConverter converter =
-                new HtmlToSpannedConverter(source, imageGetter, tagHandler,
-                        parser);
+                new HtmlToSpannedConverter(source, imageGetter, tagHandler, parser, flags);
         return converter.convert();
     }
 
     /**
+     * @deprecated use {@link #toHtml(Spanned, int)} instead.
+     */
+    @Deprecated
+    public static String toHtml(Spanned text) {
+        return toHtml(text, TO_HTML_PARAGRAPH_LINES_CONSECUTIVE);
+    }
+
+    /**
      * Returns an HTML representation of the provided Spanned text. A best effort is
      * made to add HTML tags corresponding to spans. Also note that HTML metacharacters
      * (such as "&lt;" and "&amp;") within the input text are escaped.
      *
      * @param text input text to convert
+     * @param option one of {@link #TO_HTML_PARAGRAPH_LINES_CONSECUTIVE} or
+     *     {@link #TO_HTML_PARAGRAPH_LINES_INDIVIDUAL}
      * @return string containing input converted to HTML
      */
-    public static String toHtml(Spanned text) {
+    public static String toHtml(Spanned text, int option) {
         StringBuilder out = new StringBuilder();
-        withinHtml(out, text);
+        withinHtml(out, text, option);
         return out.toString();
     }
 
@@ -159,11 +273,20 @@
         return out.toString();
     }
 
-    private static void withinHtml(StringBuilder out, Spanned text) {
+    private static void withinHtml(StringBuilder out, Spanned text, int option) {
+        if ((option & TO_HTML_PARAGRAPH_FLAG) == TO_HTML_PARAGRAPH_LINES_CONSECUTIVE) {
+            encodeTextAlignmentByDiv(out, text, option);
+            return;
+        }
+
+        withinDiv(out, text, 0, text.length(), option);
+    }
+
+    private static void encodeTextAlignmentByDiv(StringBuilder out, Spanned text, int option) {
         int len = text.length();
 
         int next;
-        for (int i = 0; i < text.length(); i = next) {
+        for (int i = 0; i < len; i = next) {
             next = text.nextSpanTransition(i, len, ParagraphStyle.class);
             ParagraphStyle[] style = text.getSpans(i, next, ParagraphStyle.class);
             String elements = " ";
@@ -187,7 +310,7 @@
                 out.append("<div ").append(elements).append(">");
             }
 
-            withinDiv(out, text, i, next);
+            withinDiv(out, text, i, next, option);
 
             if (needDiv) {
                 out.append("</div>");
@@ -195,8 +318,8 @@
         }
     }
 
-    private static void withinDiv(StringBuilder out, Spanned text,
-            int start, int end) {
+    private static void withinDiv(StringBuilder out, Spanned text, int start, int end,
+            int option) {
         int next;
         for (int i = start; i < end; i = next) {
             next = text.nextSpanTransition(i, end, QuoteSpan.class);
@@ -206,7 +329,7 @@
                 out.append("<blockquote>");
             }
 
-            withinBlockquote(out, text, i, next);
+            withinBlockquote(out, text, i, next, option);
 
             for (QuoteSpan quote : quotes) {
                 out.append("</blockquote>\n");
@@ -214,7 +337,7 @@
         }
     }
 
-    private static String getOpenParaTagWithDirection(Spanned text, int start, int end) {
+    private static String getTextDirection(Spanned text, int start, int end) {
         final int len = end - start;
         final byte[] levels = ArrayUtils.newUnpaddedByteArray(len);
         final char[] buffer = TextUtils.obtain(len);
@@ -224,16 +347,101 @@
                 false /* no info */);
         switch(paraDir) {
             case Layout.DIR_RIGHT_TO_LEFT:
-                return "<p dir=\"rtl\">";
+                return " dir=\"rtl\"";
             case Layout.DIR_LEFT_TO_RIGHT:
             default:
-                return "<p dir=\"ltr\">";
+                return " dir=\"ltr\"";
         }
     }
 
-    private static void withinBlockquote(StringBuilder out, Spanned text,
-                                         int start, int end) {
-        out.append(getOpenParaTagWithDirection(text, start, end));
+    private static String getTextStyles(Spanned text, int start, int end) {
+        final StringBuilder style = new StringBuilder(" style=\"margin-top:0; margin-bottom:0;");
+
+        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;");
+            }
+        }
+
+        style.append("\"");
+        return style.toString();
+    }
+
+    private static void withinBlockquote(StringBuilder out, Spanned text, int start, int end,
+            int option) {
+        if ((option & TO_HTML_PARAGRAPH_FLAG) == TO_HTML_PARAGRAPH_LINES_CONSECUTIVE) {
+            withinBlockquoteConsecutive(out, text, start, end);
+        } else {
+            withinBlockquoteIndividual(out, text, start, end);
+        }
+    }
+
+    private static void withinBlockquoteIndividual(StringBuilder out, Spanned text, int start,
+            int end) {
+        boolean isInList = false;
+        int next;
+        for (int i = start; i <= end; i = next) {
+            next = TextUtils.indexOf(text, '\n', i, end);
+            if (next < 0) {
+                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 (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>");
+            } else {
+                withinParagraph(out, text, i, next);
+            }
+
+            out.append("</");
+            out.append(tagType);
+            out.append(">\n");
+
+            if (next == end && isInList) {
+                isInList = false;
+                out.append("</ul>\n");
+            }
+
+            next++;
+        }
+    }
+
+    private static void withinBlockquoteConsecutive(StringBuilder out, Spanned text, int start,
+            int end) {
+        out.append("<p").append(getTextDirection(text, start, end)).append(">");
 
         int next;
         for (int i = start; i < end; i = next) {
@@ -249,25 +457,30 @@
                 next++;
             }
 
-            if (withinParagraph(out, text, i, next - nl, nl, next == end)) {
-                /* Paragraph should be closed */
-                out.append("</p>\n");
-                out.append(getOpenParaTagWithDirection(text, next, end));
+            withinParagraph(out, text, i, next - nl);
+
+            if (nl == 1) {
+                out.append("<br>\n");
+            } else {
+                for (int j = 2; j < nl; j++) {
+                    out.append("<br>");
+                }
+                if (next != end) {
+                    /* Paragraph should be closed and reopened */
+                    out.append("</p>\n");
+                    out.append("<p").append(getTextDirection(text, start, end)).append(">");
+                }
             }
         }
 
         out.append("</p>\n");
     }
 
-    /* Returns true if the caller should close and reopen the paragraph. */
-    private static boolean withinParagraph(StringBuilder out, Spanned text,
-                                        int start, int end, int nl,
-                                        boolean last) {
+    private static void withinParagraph(StringBuilder out, Spanned text, int start, int end) {
         int next;
         for (int i = start; i < end; i = next) {
             next = text.nextSpanTransition(i, end, CharacterStyle.class);
-            CharacterStyle[] style = text.getSpans(i, next,
-                                                   CharacterStyle.class);
+            CharacterStyle[] style = text.getSpans(i, next, CharacterStyle.class);
 
             for (int j = 0; j < style.length; j++) {
                 if (style[j] instanceof StyleSpan) {
@@ -297,7 +510,7 @@
                     out.append("<u>");
                 }
                 if (style[j] instanceof StrikethroughSpan) {
-                    out.append("<strike>");
+                    out.append("<span style=\"text-decoration:line-through;\">");
                 }
                 if (style[j] instanceof URLSpan) {
                     out.append("<a href=\"");
@@ -313,36 +526,51 @@
                     i = next;
                 }
                 if (style[j] instanceof AbsoluteSizeSpan) {
-                    out.append("<font size =\"");
-                    out.append(((AbsoluteSizeSpan) style[j]).getSize() / 6);
-                    out.append("\">");
+                    AbsoluteSizeSpan s = ((AbsoluteSizeSpan) style[j]);
+                    float sizeDip = s.getSize();
+                    if (!s.getDip()) {
+                        Application application = ActivityThread.currentApplication();
+                        sizeDip /= application.getResources().getDisplayMetrics().density;
+                    }
+
+                    // px in CSS is the equivalance of dip in Android
+                    out.append(String.format("<span style=\"font-size:%.0fpx\";>", sizeDip));
+                }
+                if (style[j] instanceof RelativeSizeSpan) {
+                    float sizeEm = ((RelativeSizeSpan) style[j]).getSizeChange();
+                    out.append(String.format("<span style=\"font-size:%.2fem;\">", sizeEm));
                 }
                 if (style[j] instanceof ForegroundColorSpan) {
-                    out.append("<font color =\"#");
-                    String color = Integer.toHexString(((ForegroundColorSpan)
-                            style[j]).getForegroundColor() + 0x01000000);
-                    while (color.length() < 6) {
-                        color = "0" + color;
-                    }
-                    out.append(color);
-                    out.append("\">");
+                    int color = ((ForegroundColorSpan) style[j]).getForegroundColor();
+                    out.append(String.format("<span style=\"color:#%06X;\">", 0xFFFFFF & color));
+                }
+                if (style[j] instanceof BackgroundColorSpan) {
+                    int color = ((BackgroundColorSpan) style[j]).getBackgroundColor();
+                    out.append(String.format("<span style=\"background-color:#%06X;\">",
+                            0xFFFFFF & color));
                 }
             }
 
             withinStyle(out, text, i, next);
 
             for (int j = style.length - 1; j >= 0; j--) {
+                if (style[j] instanceof BackgroundColorSpan) {
+                    out.append("</span>");
+                }
                 if (style[j] instanceof ForegroundColorSpan) {
-                    out.append("</font>");
+                    out.append("</span>");
+                }
+                if (style[j] instanceof RelativeSizeSpan) {
+                    out.append("</span>");
                 }
                 if (style[j] instanceof AbsoluteSizeSpan) {
-                    out.append("</font>");
+                    out.append("</span>");
                 }
                 if (style[j] instanceof URLSpan) {
                     out.append("</a>");
                 }
                 if (style[j] instanceof StrikethroughSpan) {
-                    out.append("</strike>");
+                    out.append("</span>");
                 }
                 if (style[j] instanceof UnderlineSpan) {
                     out.append("</u>");
@@ -372,16 +600,6 @@
                 }
             }
         }
-
-        if (nl == 1) {
-            out.append("<br>\n");
-            return false;
-        } else {
-            for (int i = 2; i < nl; i++) {
-                out.append("<br>");
-            }
-            return !last;
-        }
     }
 
     private static void withinStyle(StringBuilder out, CharSequence text,
@@ -431,15 +649,16 @@
     private SpannableStringBuilder mSpannableStringBuilder;
     private Html.ImageGetter mImageGetter;
     private Html.TagHandler mTagHandler;
+    private int mFlags;
 
-    public HtmlToSpannedConverter(
-            String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler,
-            Parser parser) {
+    public HtmlToSpannedConverter( String source, Html.ImageGetter imageGetter,
+            Html.TagHandler tagHandler, Parser parser, int flags) {
         mSource = source;
         mSpannableStringBuilder = new SpannableStringBuilder();
         mImageGetter = imageGetter;
         mTagHandler = tagHandler;
         mReader = parser;
+        mFlags = flags;
     }
 
     public Spanned convert() {
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index e34560b8..787202e 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -965,10 +965,10 @@
                         (spanStart != queryEnd && spanEnd != queryStart)) &&
                         (Object.class == kind || kind.isInstance(mSpans[i]))) {
                 int spanPriority = mSpanFlags[i] & SPAN_PRIORITY;
-                if(sort) {
-                    ret[count] = (T) mSpans[i];
-                    priority[count] = spanPriority;
-                    insertionOrder[count] = mSpanOrder[i];
+                int target = count;
+                if (sort) {
+                    priority[target] = spanPriority;
+                    insertionOrder[target] = mSpanOrder[i];
                 } else if (spanPriority != 0) {
                     //insertion sort for elements with priority
                     int j = 0;
@@ -977,8 +977,9 @@
                         if (spanPriority > p) break;
                     }
                     System.arraycopy(ret, j, ret, j + 1, count - j);
-                    ret[j] = (T) mSpans[i];
+                    target = j;
                 }
+                ret[target] = (T) mSpans[i];
                 count++;
             }
             if (count < ret.length && (i & 1) != 0) {
diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java
index 8a2d015..90a20bc 100644
--- a/core/java/android/util/LocaleList.java
+++ b/core/java/android/util/LocaleList.java
@@ -26,6 +26,8 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.Locale;
 
@@ -317,55 +319,72 @@
         return supportedScr.equals(desiredScr) ? 1 : 0;
     }
 
+    private int findFirstMatchIndex(Locale supportedLocale) {
+        for (int idx = 0; idx < mList.length; idx++) {
+            final int score = matchScore(supportedLocale, mList[idx]);
+            if (score > 0) {
+                return idx;
+            }
+        }
+        return Integer.MAX_VALUE;
+    }
+
     private static final Locale EN_LATN = Locale.forLanguageTag("en-Latn");
 
-    private Locale computeFirstMatch(String[] supportedLocales, boolean assumeEnglishIsSupported) {
+    private int computeFirstMatchIndex(Collection<String> supportedLocales,
+            boolean assumeEnglishIsSupported) {
         if (mList.length == 1) {  // just one locale, perhaps the most common scenario
-            return mList[0];
+            return 0;
         }
         if (mList.length == 0) {  // empty locale list
-            return null;
+            return -1;
         }
+
         int bestIndex = Integer.MAX_VALUE;
-        final int numSupportedLocales =
-                supportedLocales.length + (assumeEnglishIsSupported ? 1 : 0);
-        for (int i = 0; i < numSupportedLocales; i++) {
-            final Locale supportedLocale;
-            if (assumeEnglishIsSupported) {
-                // Try English first, so we can return early if it's in the LocaleList
-                supportedLocale = (i == 0) ? EN_LATN : Locale.forLanguageTag(supportedLocales[i-1]);
-            } else {
-                supportedLocale = Locale.forLanguageTag(supportedLocales[i]);
+        // Try English first, so we can return early if it's in the LocaleList
+        if (assumeEnglishIsSupported) {
+            final int idx = findFirstMatchIndex(EN_LATN);
+            if (idx == 0) { // We have a match on the first locale, which is good enough
+                return 0;
+            } else if (idx < bestIndex) {
+                bestIndex = idx;
             }
+        }
+        for (String languageTag : supportedLocales) {
+            final Locale supportedLocale = Locale.forLanguageTag(languageTag);
             // We expect the average length of locale lists used for locale resolution to be
             // smaller than three, so it's OK to do this as an O(mn) algorithm.
-            for (int idx = 0; idx < mList.length; idx++) {
-                final int score = matchScore(supportedLocale, mList[idx]);
-                if (score > 0) {
-                    if (idx == 0) {  // We have a match on the first locale, which is good enough
-                        return mList[0];
-                    } else if (idx < bestIndex) {
-                        bestIndex = idx;
-                    }
-                }
+            final int idx = findFirstMatchIndex(supportedLocale);
+            if (idx == 0) { // We have a match on the first locale, which is good enough
+                return 0;
+            } else if (idx < bestIndex) {
+                bestIndex = idx;
             }
         }
-        if (bestIndex == Integer.MAX_VALUE) {  // no match was found
-            return mList[0];
+        if (bestIndex == Integer.MAX_VALUE) {
+            // no match was found, so we fall back to the first locale in the locale list
+            return 0;
         } else {
-            return mList[bestIndex];
+            return bestIndex;
         }
     }
 
+    private Locale computeFirstMatch(Collection<String> supportedLocales,
+            boolean assumeEnglishIsSupported) {
+        int bestIndex = computeFirstMatchIndex(supportedLocales, assumeEnglishIsSupported);
+        return bestIndex == -1 ? null : mList[bestIndex];
+    }
+
     /**
      * Returns the first match in the locale list given an unordered array of supported locales
-     * in BCP47 format.
+     * in BCP 47 format.
      *
      * If the locale list is empty, null would be returned.
      */
     @Nullable
     public Locale getFirstMatch(String[] supportedLocales) {
-        return computeFirstMatch(supportedLocales, false /* assume English is not supported */);
+        return computeFirstMatch(Arrays.asList(supportedLocales),
+                false /* assume English is not supported */);
     }
 
     /**
@@ -374,11 +393,26 @@
      */
     @Nullable
     public Locale getFirstMatchWithEnglishSupported(String[] supportedLocales) {
-        return computeFirstMatch(supportedLocales, true /* assume English is supported */);
+        return computeFirstMatch(Arrays.asList(supportedLocales),
+                true /* assume English is supported */);
     }
 
     /**
-     * Returns true if the array of locale tags only contains empty locales and pseudolocales.
+     * {@hide}
+     */
+    public int getFirstMatchIndexWithEnglishSupported(Collection<String> supportedLocales) {
+        return computeFirstMatchIndex(supportedLocales, true /* assume English is supported */);
+    }
+
+    /**
+     * {@hide}
+     */
+    public int getFirstMatchIndexWithEnglishSupported(String[] supportedLocales) {
+        return getFirstMatchIndexWithEnglishSupported(Arrays.asList(supportedLocales));
+    }
+
+    /**
+     * Returns true if the collection of locale tags only contains empty locales and pseudolocales.
      * Assumes that there is no repetition in the input.
      * {@hide}
      */
@@ -386,7 +420,7 @@
         if (supportedLocales.length > NUM_PSEUDO_LOCALES + 1) {
             // This is for optimization. Since there's no repetition in the input, if we have more
             // than the number of pseudo-locales plus one for the empty string, it's guaranteed
-            // that we have some meaninful locale in the list, so the list is not "practically
+            // that we have some meaninful locale in the collection, so the list is not "practically
             // empty".
             return false;
         }
@@ -405,6 +439,8 @@
     @GuardedBy("sLock")
     private static LocaleList sDefaultLocaleList = null;
     @GuardedBy("sLock")
+    private static LocaleList sDefaultAdjustedLocaleList = null;
+    @GuardedBy("sLock")
     private static Locale sLastDefaultLocale = null;
 
     /**
@@ -415,8 +451,8 @@
      * secondary preference is.
      *
      * Note that the default LocaleList would change if Locale.setDefault() is called. This method
-     * takes that into account by always checking the output of Locale.getDefault() and adjusting
-     * the default LocaleList if needed.
+     * takes that into account by always checking the output of Locale.getDefault() and
+     * recalculating the default LocaleList if needed.
      */
     @NonNull @Size(min=1)
     public static LocaleList getDefault() {
@@ -426,7 +462,7 @@
                 sLastDefaultLocale = defaultLocale;
                 // It's either the first time someone has asked for the default locale list, or
                 // someone has called Locale.setDefault() since we last set or adjusted the default
-                // locale list. So let's adjust the locale list.
+                // locale list. So let's recalculate the locale list.
                 if (sDefaultLocaleList != null
                         && defaultLocale.equals(sDefaultLocaleList.getPrimary())) {
                     // The default Locale has changed, but it happens to be the first locale in the
@@ -434,6 +470,7 @@
                     return sDefaultLocaleList;
                 }
                 sDefaultLocaleList = new LocaleList(defaultLocale, sLastExplicitlySetLocaleList);
+                sDefaultAdjustedLocaleList = sDefaultLocaleList;
             }
             // sDefaultLocaleList can't be null, since it can't be set to null by
             // LocaleList.setDefault(), and if getDefault() is called before a call to
@@ -444,6 +481,20 @@
     }
 
     /**
+     * Returns the default locale list, adjusted by moving the default locale to its first
+     * position.
+     *
+     * {@hide}
+     */
+    @NonNull @Size(min=1)
+    public static LocaleList getAdjustedDefault() {
+        getDefault(); // to recalculate the default locale list, if necessary
+        synchronized (sLock) {
+            return sDefaultAdjustedLocaleList;
+        }
+    }
+
+    /**
      * Also sets the default locale by calling Locale.setDefault() with the first locale in the
      * list.
      *
@@ -474,6 +525,12 @@
             Locale.setDefault(sLastDefaultLocale);
             sLastExplicitlySetLocaleList = locales;
             sDefaultLocaleList = locales;
+            if (localeIndex == 0) {
+                sDefaultAdjustedLocaleList = sDefaultLocaleList;
+            } else {
+                sDefaultAdjustedLocaleList = new LocaleList(
+                        sLastDefaultLocale, sDefaultLocaleList);
+            }
         }
     }
 }
diff --git a/core/java/android/view/DropPermissions.java b/core/java/android/view/DropPermissions.java
index 8c948a9..5411dad 100644
--- a/core/java/android/view/DropPermissions.java
+++ b/core/java/android/view/DropPermissions.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.app.ActivityManagerNative;
 import android.os.IBinder;
 import android.os.RemoteException;
 import com.android.internal.view.IDropPermissions;
@@ -41,6 +42,8 @@
 
     private final IDropPermissions mDropPermissions;
 
+    private IBinder mPermissionOwnerToken;
+
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
     /**
@@ -80,11 +83,29 @@
     }
 
     /**
+     * Take the permissions. Must call {@link #release} explicitly.
+     * @return True if permissions are successfully taken.
+     * @hide
+     */
+    public boolean takeTransient() {
+        try {
+            mPermissionOwnerToken = ActivityManagerNative.getDefault().
+                    newUriPermissionOwner("drop");
+            mDropPermissions.takeTransient(mPermissionOwnerToken);
+        } catch (RemoteException e) {
+            return false;
+        }
+        mCloseGuard.open("release");
+        return true;
+    }
+
+    /**
      * Revoke permissions explicitly.
      */
     public void release() {
         try {
             mDropPermissions.release();
+            mPermissionOwnerToken = null;
         } catch (RemoteException e) {
         }
         mCloseGuard.close();
diff --git a/core/java/android/view/FrameStatsObserver.java b/core/java/android/view/FrameStatsObserver.java
new file mode 100644
index 0000000..0add607
--- /dev/null
+++ b/core/java/android/view/FrameStatsObserver.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 9231394..c5ed39a 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -76,6 +76,11 @@
     void dispatchDragEvent(in DragEvent event);
 
     /**
+     * Pointer icon events
+     */
+    void updatePointerIcon(float x, float y);
+
+    /**
      * System chrome visibility changes
      */
     void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 1a5de7e..1703ed1 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -186,8 +186,8 @@
     /**
      * Initiate the drag operation itself
      */
-    boolean performDrag(IWindow window, IBinder dragToken, float touchX, float touchY,
-            float thumbCenterX, float thumbCenterY, in ClipData data);
+    boolean performDrag(IWindow window, IBinder dragToken, int touchSource,
+            float touchX, float touchY, float thumbCenterX, float thumbCenterY, in ClipData data);
 
    /**
      * Report the result of a drop action targeted to the given window.
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 0e4bc84..78a63a6 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -24,7 +24,9 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Binder;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -34,12 +36,14 @@
 import android.view.View.AttachInfo;
 
 import com.android.internal.R;
+import com.android.internal.util.VirtualRefBasePtr;
 
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.HashSet;
 
 /**
  * Hardware renderer that proxies the rendering to a render thread. Most calls
@@ -339,6 +343,8 @@
     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);
@@ -947,6 +953,31 @@
         }
     }
 
+    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 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);
+    }
+
     static native void setupShadersDiskCache(String cacheFile);
 
     private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
@@ -1000,4 +1031,8 @@
     private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
     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);
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2a7b92d..dd0887f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -100,16 +100,17 @@
 import android.widget.Checkable;
 import android.widget.FrameLayout;
 import android.widget.ScrollBarDrawable;
-
 import static android.os.Build.VERSION_CODES.*;
 import static java.lang.Math.max;
 
 import com.android.internal.R;
 import com.android.internal.util.Predicate;
 import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.widget.ScrollBarUtils;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
+import java.lang.NullPointerException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
@@ -3702,6 +3703,11 @@
     private ViewPropertyAnimator mAnimator = null;
 
     /**
+     * List of FrameStatsObservers pending registration when mAttachInfo is null.
+     */
+    private ArrayList<FrameStatsObserver> mPendingFrameStatsObservers;
+
+    /**
      * Flag indicating that a drag can cross window boundaries.  When
      * {@link #startDragAndDrop(ClipData, DragShadowBuilder, Object, int)} is called
      * with this flag set, all visible applications will be able to participate
@@ -5122,6 +5128,88 @@
         return mVerticalScrollbarPosition;
     }
 
+    boolean isOnScrollbar(float x, float y) {
+        if (mScrollCache == null) {
+            return false;
+        }
+        x += getScrollX();
+        y += getScrollY();
+        if (isVerticalScrollBarEnabled() && !isVerticalScrollBarHidden()) {
+            final Rect bounds = mScrollCache.mScrollBarBounds;
+            getVerticalScrollBarBounds(bounds);
+            if (bounds.contains((int)x, (int)y)) {
+                return true;
+            }
+        }
+        if (isHorizontalScrollBarEnabled()) {
+            final Rect bounds = mScrollCache.mScrollBarBounds;
+            getHorizontalScrollBarBounds(bounds);
+            if (bounds.contains((int)x, (int)y)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean isOnScrollbarThumb(float x, float y) {
+        return isOnVerticalScrollbarThumb(x, y) || isOnHorizontalScrollbarThumb(x, y);
+    }
+
+    private boolean isOnVerticalScrollbarThumb(float x, float y) {
+        if (mScrollCache == null) {
+            return false;
+        }
+        if (isVerticalScrollBarEnabled() && !isVerticalScrollBarHidden()) {
+            x += getScrollX();
+            y += getScrollY();
+            final Rect bounds = mScrollCache.mScrollBarBounds;
+            getVerticalScrollBarBounds(bounds);
+            final int range = computeVerticalScrollRange();
+            final int offset = computeVerticalScrollOffset();
+            final int extent = computeVerticalScrollExtent();
+            final int thumbLength = ScrollBarUtils.getThumbLength(bounds.height(), bounds.width(),
+                    extent, range);
+            final int thumbOffset = ScrollBarUtils.getThumbOffset(bounds.height(), thumbLength,
+                    extent, range, offset);
+            final int thumbTop = bounds.top + thumbOffset;
+            if (x >= bounds.left && x <= bounds.right && y >= thumbTop
+                    && y <= thumbTop + thumbLength) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isOnHorizontalScrollbarThumb(float x, float y) {
+        if (mScrollCache == null) {
+            return false;
+        }
+        if (isHorizontalScrollBarEnabled()) {
+            x += getScrollX();
+            y += getScrollY();
+            final Rect bounds = mScrollCache.mScrollBarBounds;
+            getHorizontalScrollBarBounds(bounds);
+            final int range = computeHorizontalScrollRange();
+            final int offset = computeHorizontalScrollOffset();
+            final int extent = computeHorizontalScrollExtent();
+            final int thumbLength = ScrollBarUtils.getThumbLength(bounds.width(), bounds.height(),
+                    extent, range);
+            final int thumbOffset = ScrollBarUtils.getThumbOffset(bounds.width(), thumbLength,
+                    extent, range, offset);
+            final int thumbLeft = bounds.left + thumbOffset;
+            if (x >= thumbLeft && x <= thumbLeft + thumbLength && y >= bounds.top
+                    && y <= bounds.bottom) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean isDraggingScrollBar() {
+        return mScrollCache != null
+                && mScrollCache.mScrollBarDraggingState != ScrollabilityCache.NOT_DRAGGING;
+    }
+
     /**
      * Sets the state of all scroll indicators.
      * <p>
@@ -5381,6 +5469,58 @@
     }
 
     /**
+     * Set an observer to collect stats for each frame rendered for this view.
+     *
+     * @hide
+     */
+    public void addFrameStatsObserver(FrameStatsObserver fso) {
+        if (mAttachInfo != null) {
+            if (mAttachInfo.mHardwareRenderer != null) {
+                mAttachInfo.mHardwareRenderer.addFrameStatsObserver(fso);
+            } else {
+                Log.w(VIEW_LOG_TAG, "View not hardware-accelerated. Unable to observe frame stats");
+            }
+        } else {
+            if (mPendingFrameStatsObservers == null) {
+                mPendingFrameStatsObservers = new ArrayList<>();
+            }
+
+            mPendingFrameStatsObservers.add(fso);
+        }
+    }
+
+    /**
+     * Remove observer configured to collect frame stats for this view.
+     *
+     * @hide
+     */
+    public void removeFrameStatsObserver(FrameStatsObserver fso) {
+        ThreadedRenderer renderer = getHardwareRenderer();
+
+        if (mPendingFrameStatsObservers != null) {
+            mPendingFrameStatsObservers.remove(fso);
+        }
+
+        if (renderer != null) {
+            renderer.removeFrameStatsObserver(fso);
+        }
+    }
+
+    private void registerPendingFrameStatsObservers() {
+        if (mPendingFrameStatsObservers != null) {
+            ThreadedRenderer renderer = getHardwareRenderer();
+            if (renderer != null) {
+                for (FrameStatsObserver fso : mPendingFrameStatsObservers) {
+                    renderer.addFrameStatsObserver(fso);
+                }
+            } else {
+                Log.w(VIEW_LOG_TAG, "View not hardware-accelerated. Unable to observe frame stats");
+            }
+            mPendingFrameStatsObservers = null;
+        }
+    }
+
+    /**
      * Call this view's OnClickListener, if it is defined.  Performs all normal
      * actions associated with clicking: reporting accessibility event, playing
      * a sound, etc.
@@ -5737,8 +5877,11 @@
      * <p>A View should call this if it maintains some notion of which part
      * of its content is interesting.  For example, a text editing view
      * should call this when its cursor moves.
+     * <p>The Rectangle passed into this method should be in the View's content coordinate space.
+     * It should not be affected by which part of the View is currently visible or its scroll
+     * position.
      *
-     * @param rectangle The rectangle.
+     * @param rectangle The rectangle in the View's content coordinate space
      * @return Whether any parent scrolled.
      */
     public boolean requestRectangleOnScreen(Rect rectangle) {
@@ -5752,11 +5895,13 @@
      * <p>A View should call this if it maintains some notion of which part
      * of its content is interesting.  For example, a text editing view
      * should call this when its cursor moves.
-     *
+     * <p>The Rectangle passed into this method should be in the View's content coordinate space.
+     * It should not be affected by which part of the View is currently visible or its scroll
+     * position.
      * <p>When <code>immediate</code> is set to true, scrolling will not be
      * animated.
      *
-     * @param rectangle The rectangle.
+     * @param rectangle The rectangle in the View's content coordinate space
      * @param immediate True to forbid animated scrolling, false otherwise
      * @return Whether any parent scrolled.
      */
@@ -5776,24 +5921,16 @@
             rectangle.set((int) position.left, (int) position.top,
                     (int) position.right, (int) position.bottom);
 
-            scrolled |= parent.requestChildRectangleOnScreen(child,
-                    rectangle, immediate);
-
-            if (!child.hasIdentityMatrix()) {
-                child.getMatrix().mapRect(position);
-            }
-
-            position.offset(child.mLeft, child.mTop);
+            scrolled |= parent.requestChildRectangleOnScreen(child, rectangle, immediate);
 
             if (!(parent instanceof View)) {
                 break;
             }
 
-            View parentView = (View) parent;
+            // move it from child's content coordinate space to parent's content coordinate space
+            position.offset(child.mLeft - child.getScrollX(), child.mTop -child.getScrollY());
 
-            position.offset(-parentView.getScrollX(), -parentView.getScrollY());
-
-            child = parentView;
+            child = (View) parent;
             parent = child.getParent();
         }
 
@@ -9660,6 +9797,9 @@
         }
 
         if (onFilterTouchEventForSecurity(event)) {
+            if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
+                result = true;
+            }
             //noinspection SimplifiableIfStatement
             ListenerInfo li = mListenerInfo;
             if (li != null && li.mOnTouchListener != null
@@ -10524,6 +10664,11 @@
             }
         }
 
+        if ((action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_MOVE)
+                && event.isFromSource(InputDevice.SOURCE_MOUSE)
+                && isOnScrollbar(event.getX(), event.getY())) {
+            awakenScrollBars();
+        }
         if (isHoverable()) {
             switch (action) {
                 case MotionEvent.ACTION_HOVER_ENTER:
@@ -10627,6 +10772,110 @@
     }
 
     /**
+     * Handles scroll bar dragging by mouse input.
+     *
+     * @hide
+     * @param event The motion event.
+     *
+     * @return true if the event was handled as a scroll bar dragging, false otherwise.
+     */
+    protected boolean handleScrollBarDragging(MotionEvent event) {
+        if (mScrollCache == null) {
+            return false;
+        }
+        final float x = event.getX();
+        final float y = event.getY();
+        final int action = event.getAction();
+        if ((mScrollCache.mScrollBarDraggingState == ScrollabilityCache.NOT_DRAGGING
+                && action != MotionEvent.ACTION_DOWN)
+                    || !event.isFromSource(InputDevice.SOURCE_MOUSE)
+                    || !event.isButtonPressed(MotionEvent.BUTTON_PRIMARY)) {
+            mScrollCache.mScrollBarDraggingState = ScrollabilityCache.NOT_DRAGGING;
+            return false;
+        }
+
+        switch (action) {
+            case MotionEvent.ACTION_MOVE:
+                if (mScrollCache.mScrollBarDraggingState == ScrollabilityCache.NOT_DRAGGING) {
+                    return false;
+                }
+                if (mScrollCache.mScrollBarDraggingState
+                        == ScrollabilityCache.DRAGGING_VERTICAL_SCROLL_BAR) {
+                    final Rect bounds = mScrollCache.mScrollBarBounds;
+                    getVerticalScrollBarBounds(bounds);
+                    final int range = computeVerticalScrollRange();
+                    final int offset = computeVerticalScrollOffset();
+                    final int extent = computeVerticalScrollExtent();
+
+                    final int thumbLength = ScrollBarUtils.getThumbLength(
+                            bounds.height(), bounds.width(), extent, range);
+                    final int thumbOffset = ScrollBarUtils.getThumbOffset(
+                            bounds.height(), thumbLength, extent, range, offset);
+
+                    final float diff = y - mScrollCache.mScrollBarDraggingPos;
+                    final float maxThumbOffset = bounds.height() - thumbLength;
+                    final float newThumbOffset =
+                            Math.min(Math.max(thumbOffset + diff, 0.0f), maxThumbOffset);
+                    final int height = getHeight();
+                    if (Math.round(newThumbOffset) != thumbOffset && maxThumbOffset > 0
+                            && height > 0 && extent > 0) {
+                        final int newY = Math.round((range - extent)
+                                / ((float)extent / height) * (newThumbOffset / maxThumbOffset));
+                        if (newY != getScrollY()) {
+                            mScrollCache.mScrollBarDraggingPos = y;
+                            setScrollY(newY);
+                        }
+                    }
+                    return true;
+                }
+                if (mScrollCache.mScrollBarDraggingState
+                        == ScrollabilityCache.DRAGGING_HORIZONTAL_SCROLL_BAR) {
+                    final Rect bounds = mScrollCache.mScrollBarBounds;
+                    getHorizontalScrollBarBounds(bounds);
+                    final int range = computeHorizontalScrollRange();
+                    final int offset = computeHorizontalScrollOffset();
+                    final int extent = computeHorizontalScrollExtent();
+
+                    final int thumbLength = ScrollBarUtils.getThumbLength(
+                            bounds.width(), bounds.height(), extent, range);
+                    final int thumbOffset = ScrollBarUtils.getThumbOffset(
+                            bounds.width(), thumbLength, extent, range, offset);
+
+                    final float diff = x - mScrollCache.mScrollBarDraggingPos;
+                    final float maxThumbOffset = bounds.width() - thumbLength;
+                    final float newThumbOffset =
+                            Math.min(Math.max(thumbOffset + diff, 0.0f), maxThumbOffset);
+                    final int width = getWidth();
+                    if (Math.round(newThumbOffset) != thumbOffset && maxThumbOffset > 0
+                            && width > 0 && extent > 0) {
+                        final int newX = Math.round((range - extent)
+                                / ((float)extent / width) * (newThumbOffset / maxThumbOffset));
+                        if (newX != getScrollX()) {
+                            mScrollCache.mScrollBarDraggingPos = x;
+                            setScrollX(newX);
+                        }
+                    }
+                    return true;
+                }
+            case MotionEvent.ACTION_DOWN:
+                if (isOnVerticalScrollbarThumb(x, y)) {
+                    mScrollCache.mScrollBarDraggingState =
+                            ScrollabilityCache.DRAGGING_VERTICAL_SCROLL_BAR;
+                    mScrollCache.mScrollBarDraggingPos = y;
+                    return true;
+                }
+                if (isOnHorizontalScrollbarThumb(x, y)) {
+                    mScrollCache.mScrollBarDraggingState =
+                            ScrollabilityCache.DRAGGING_HORIZONTAL_SCROLL_BAR;
+                    mScrollCache.mScrollBarDraggingPos = x;
+                    return true;
+                }
+        }
+        mScrollCache.mScrollBarDraggingState = ScrollabilityCache.NOT_DRAGGING;
+        return false;
+    }
+
+    /**
      * Implement this method to handle touch screen motion events.
      * <p>
      * If this method is used to detect click actions, it is recommended that
@@ -10659,7 +10908,6 @@
                     || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
                     || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE);
         }
-
         if (mTouchDelegate != null) {
             if (mTouchDelegate.onTouchEvent(event)) {
                 return true;
@@ -14220,6 +14468,45 @@
         }
     }
 
+    private void getHorizontalScrollBarBounds(Rect bounds) {
+        final int inside = (mViewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
+        final boolean drawVerticalScrollBar = isVerticalScrollBarEnabled()
+                && !isVerticalScrollBarHidden();
+        final int size = getHorizontalScrollbarHeight();
+        final int verticalScrollBarGap = drawVerticalScrollBar ?
+                getVerticalScrollbarWidth() : 0;
+        final int width = mRight - mLeft;
+        final int height = mBottom - mTop;
+        bounds.top = mScrollY + height - size - (mUserPaddingBottom & inside);
+        bounds.left = mScrollX + (mPaddingLeft & inside);
+        bounds.right = mScrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
+        bounds.bottom = bounds.top + size;
+    }
+
+    private void getVerticalScrollBarBounds(Rect bounds) {
+        final int inside = (mViewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
+        final int size = getVerticalScrollbarWidth();
+        int verticalScrollbarPosition = mVerticalScrollbarPosition;
+        if (verticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
+            verticalScrollbarPosition = isLayoutRtl() ?
+                    SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
+        }
+        final int width = mRight - mLeft;
+        final int height = mBottom - mTop;
+        switch (verticalScrollbarPosition) {
+            default:
+            case SCROLLBAR_POSITION_RIGHT:
+                bounds.left = mScrollX + width - size - (mUserPaddingRight & inside);
+                break;
+            case SCROLLBAR_POSITION_LEFT:
+                bounds.left = mScrollX + (mUserPaddingLeft & inside);
+                break;
+        }
+        bounds.top = mScrollY + (mPaddingTop & inside);
+        bounds.right = bounds.left + size;
+        bounds.bottom = mScrollY + height - (mUserPaddingBottom & inside);
+    }
+
     /**
      * <p>Request the drawing of the horizontal and the vertical scrollbar. The
      * scrollbars are painted only if they have been awakened first.</p>
@@ -14267,80 +14554,36 @@
                 cache.scrollBar.mutate().setAlpha(255);
             }
 
-
-            final int viewFlags = mViewFlags;
-
-            final boolean drawHorizontalScrollBar =
-                (viewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
-            final boolean drawVerticalScrollBar =
-                (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL
-                && !isVerticalScrollBarHidden();
+            final boolean drawHorizontalScrollBar = isHorizontalScrollBarEnabled();
+            final boolean drawVerticalScrollBar = isVerticalScrollBarEnabled()
+                    && !isVerticalScrollBarHidden();
 
             if (drawVerticalScrollBar || drawHorizontalScrollBar) {
-                final int width = mRight - mLeft;
-                final int height = mBottom - mTop;
-
                 final ScrollBarDrawable scrollBar = cache.scrollBar;
 
-                final int scrollX = mScrollX;
-                final int scrollY = mScrollY;
-                final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
-
-                int left;
-                int top;
-                int right;
-                int bottom;
-
                 if (drawHorizontalScrollBar) {
-                    int size = scrollBar.getSize(false);
-                    if (size <= 0) {
-                        size = cache.scrollBarSize;
-                    }
-
                     scrollBar.setParameters(computeHorizontalScrollRange(),
                                             computeHorizontalScrollOffset(),
                                             computeHorizontalScrollExtent(), false);
-                    final int verticalScrollBarGap = drawVerticalScrollBar ?
-                            getVerticalScrollbarWidth() : 0;
-                    top = scrollY + height - size - (mUserPaddingBottom & inside);
-                    left = scrollX + (mPaddingLeft & inside);
-                    right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
-                    bottom = top + size;
-                    onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
+                    final Rect bounds = cache.mScrollBarBounds;
+                    getHorizontalScrollBarBounds(bounds);
+                    onDrawHorizontalScrollBar(canvas, scrollBar, bounds.left, bounds.top,
+                            bounds.right, bounds.bottom);
                     if (invalidate) {
-                        invalidate(left, top, right, bottom);
+                        invalidate(bounds);
                     }
                 }
 
                 if (drawVerticalScrollBar) {
-                    int size = scrollBar.getSize(true);
-                    if (size <= 0) {
-                        size = cache.scrollBarSize;
-                    }
-
                     scrollBar.setParameters(computeVerticalScrollRange(),
                                             computeVerticalScrollOffset(),
                                             computeVerticalScrollExtent(), true);
-                    int verticalScrollbarPosition = mVerticalScrollbarPosition;
-                    if (verticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
-                        verticalScrollbarPosition = isLayoutRtl() ?
-                                SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
-                    }
-                    switch (verticalScrollbarPosition) {
-                        default:
-                        case SCROLLBAR_POSITION_RIGHT:
-                            left = scrollX + width - size - (mUserPaddingRight & inside);
-                            break;
-                        case SCROLLBAR_POSITION_LEFT:
-                            left = scrollX + (mUserPaddingLeft & inside);
-                            break;
-                    }
-                    top = scrollY + (mPaddingTop & inside);
-                    right = left + size;
-                    bottom = scrollY + height - (mUserPaddingBottom & inside);
-                    onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
+                    final Rect bounds = cache.mScrollBarBounds;
+                    getVerticalScrollBarBounds(bounds);
+                    onDrawVerticalScrollBar(canvas, scrollBar, bounds.left, bounds.top,
+                            bounds.right, bounds.bottom);
                     if (invalidate) {
-                        invalidate(left, top, right, bottom);
+                        invalidate(bounds);
                     }
                 }
             }
@@ -14903,6 +15146,9 @@
             info.mTreeObserver.merge(mFloatingTreeObserver);
             mFloatingTreeObserver = null;
         }
+
+        registerPendingFrameStatsObservers();
+
         if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) {
             mAttachInfo.mScrollContainers.add(this);
             mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
@@ -20059,7 +20305,7 @@
                 root.getLastTouchPoint(shadowSize);
 
                 okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, mAttachInfo.mDragToken,
-                        shadowSize.x, shadowSize.y,
+                        root.getLastTouchSource(), shadowSize.x, shadowSize.y,
                         shadowTouchPoint.x, shadowTouchPoint.y, data);
                 if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
             }
@@ -21277,6 +21523,9 @@
      * @see PointerIcon
      */
     public PointerIcon getPointerIcon(MotionEvent event, float x, float y) {
+        if (isDraggingScrollBar() || isOnScrollbarThumb(x, y)) {
+            return PointerIcon.getSystemIcon(mContext, PointerIcon.STYLE_ARROW);
+        }
         return mPointerIcon;
     }
 
@@ -22548,6 +22797,15 @@
 
         private int mLastColor;
 
+        public final Rect mScrollBarBounds = new Rect();
+
+        public static final int NOT_DRAGGING = 0;
+        public static final int DRAGGING_VERTICAL_SCROLL_BAR = 1;
+        public static final int DRAGGING_HORIZONTAL_SCROLL_BAR = 2;
+        public int mScrollBarDraggingState = NOT_DRAGGING;
+
+        public float mScrollBarDraggingPos = 0;
+
         public ScrollabilityCache(ViewConfiguration configuration, View host) {
             fadingEdgeLength = configuration.getScaledFadingEdgeLength();
             scrollBarSize = configuration.getScaledScrollBarSize();
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 27e2ea3..3fe6b8e 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -59,6 +59,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
 
 /**
@@ -1651,6 +1652,9 @@
 
     @Override
     public PointerIcon getPointerIcon(MotionEvent event, float x, float y) {
+        if (isOnScrollbarThumb(x, y) || isDraggingScrollBar()) {
+            return PointerIcon.getSystemIcon(mContext, PointerIcon.STYLE_ARROW);
+        }
         // Check what the child under the pointer says about the pointer.
         final int childrenCount = mChildrenCount;
         if (childrenCount != 0) {
@@ -1974,7 +1978,7 @@
      * hover exit event in {@link #onHoverEvent} and then the hovered child will
      * receive a hover enter event.
      * </p><p>
-     * The default implementation always returns false.
+     * The default implementation handles mouse hover on the scroll bars.
      * </p>
      *
      * @param event The motion event that describes the hover.
@@ -1982,6 +1986,15 @@
      * and prevent its children from receiving it.
      */
     public boolean onInterceptHoverEvent(MotionEvent event) {
+        if (event.isFromSource(InputDevice.SOURCE_MOUSE)) {
+            final int action = event.getAction();
+            final float x = event.getX();
+            final float y = event.getY();
+            if ((action == MotionEvent.ACTION_HOVER_MOVE
+                    || action == MotionEvent.ACTION_HOVER_ENTER) && isOnScrollbar(x, y)) {
+                return true;
+            }
+        }
         return false;
     }
 
@@ -2716,6 +2729,12 @@
      * messages will be delivered here.
      */
     public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (ev.isFromSource(InputDevice.SOURCE_MOUSE)
+                && ev.getAction() == MotionEvent.ACTION_DOWN
+                && ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
+                && isOnScrollbarThumb(ev.getX(), ev.getY())) {
+            return true;
+        }
         return false;
     }
 
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index e9b123b5..1962be8 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -266,14 +266,14 @@
      *            intercept touch events.
      */
     public void requestDisallowInterceptTouchEvent(boolean disallowIntercept);
-    
+
     /**
      * Called when a child of this group wants a particular rectangle to be
      * positioned onto the screen.  {@link ViewGroup}s overriding this can trust
      * that:
      * <ul>
      *   <li>child will be a direct child of this group</li>
-     *   <li>rectangle will be in the child's coordinates</li>
+     *   <li>rectangle will be in the child's content coordinates</li>
      * </ul>
      *
      * <p>{@link ViewGroup}s overriding this should uphold the contract:</p>
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1bb0311..5d41477 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -339,6 +339,7 @@
     volatile Object mLocalDragState;
     final PointF mDragPoint = new PointF();
     final PointF mLastTouchPoint = new PointF();
+    int mLastTouchSource;
 
     private boolean mProfileRendering;
     private Choreographer.FrameCallback mRenderProfiler;
@@ -3277,6 +3278,7 @@
     private final static int MSG_SYNTHESIZE_INPUT_EVENT = 24;
     private final static int MSG_DISPATCH_WINDOW_SHOWN = 25;
     private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26;
+    private final static int MSG_UPDATE_POINTER_ICON = 27;
 
     final class ViewRootHandler extends Handler {
         @Override
@@ -3326,6 +3328,8 @@
                     return "MSG_SYNTHESIZE_INPUT_EVENT";
                 case MSG_DISPATCH_WINDOW_SHOWN:
                     return "MSG_DISPATCH_WINDOW_SHOWN";
+                case MSG_UPDATE_POINTER_ICON:
+                    return "MSG_UPDATE_POINTER_ICON";
             }
             return super.getMessageName(message);
         }
@@ -3567,6 +3571,10 @@
                 IResultReceiver receiver = (IResultReceiver) msg.obj;
                 handleRequestKeyboardShortcuts(receiver);
             } break;
+            case MSG_UPDATE_POINTER_ICON: {
+                MotionEvent event = (MotionEvent) msg.obj;
+                resetPointerIcon(event);
+            } break;
             }
         }
     }
@@ -4122,6 +4130,7 @@
             if (event.isTouchEvent()) {
                 mLastTouchPoint.x = event.getRawX();
                 mLastTouchPoint.y = event.getRawY();
+                mLastTouchSource = event.getSource();
             }
             return FORWARD;
         }
@@ -4307,31 +4316,11 @@
                     mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED;
                 }
 
-                final float x = event.getX();
-                final float y = event.getY();
-                if (event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT
-                        && x >= 0 && x < mView.getWidth() && y >= 0 && y < mView.getHeight()) {
-                    PointerIcon pointerIcon = mView.getPointerIcon(event, x, y);
-                    int pointerShape = (pointerIcon != null) ?
-                            pointerIcon.getStyle() : PointerIcon.STYLE_DEFAULT;
-
-                    final InputDevice inputDevice = event.getDevice();
-                    if (inputDevice != null) {
-                        if (mPointerIconShape != pointerShape) {
-                            mPointerIconShape = pointerShape;
-                            if (mPointerIconShape != PointerIcon.STYLE_CUSTOM) {
-                                mCustomPointerIcon = null;
-                                inputDevice.setPointerShape(pointerShape);
-                            }
-                        }
-                        if (mPointerIconShape == PointerIcon.STYLE_CUSTOM &&
-                                !pointerIcon.equals(mCustomPointerIcon)) {
-                            mCustomPointerIcon = pointerIcon;
-                            inputDevice.setCustomPointerIcon(mCustomPointerIcon);
-                        }
+                if (event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) {
+                    if (!updatePointerIcon(event) &&
+                            event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) {
+                        mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED;
                     }
-                } else if (event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) {
-                    mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED;
                 }
             }
 
@@ -4369,6 +4358,38 @@
         }
     }
 
+    private void resetPointerIcon(MotionEvent event) {
+        mPointerIconShape = PointerIcon.STYLE_NOT_SPECIFIED;
+        updatePointerIcon(event);
+    }
+
+    private boolean updatePointerIcon(MotionEvent event) {
+        final float x = event.getX();
+        final float y = event.getY();
+        if (x < 0 || x >= mView.getWidth() || y < 0 || y >= mView.getHeight()) {
+            Slog.e(mTag, "updatePointerIcon called with position out of bounds");
+            return false;
+        }
+        final PointerIcon pointerIcon = mView.getPointerIcon(event, x, y);
+        final int pointerShape = (pointerIcon != null) ?
+                pointerIcon.getStyle() : PointerIcon.STYLE_DEFAULT;
+
+        if (mPointerIconShape != pointerShape) {
+            mPointerIconShape = pointerShape;
+            if (mPointerIconShape != PointerIcon.STYLE_CUSTOM) {
+                mCustomPointerIcon = null;
+                InputManager.getInstance().setPointerIconShape(pointerShape);
+                return true;
+            }
+        }
+        if (mPointerIconShape == PointerIcon.STYLE_CUSTOM &&
+                !pointerIcon.equals(mCustomPointerIcon)) {
+            mCustomPointerIcon = pointerIcon;
+            InputManager.getInstance().setCustomPointerIcon(mCustomPointerIcon);
+        }
+        return true;
+    }
+
     /**
      * Performs synthesis of new input events from unhandled input events.
      */
@@ -5475,6 +5496,10 @@
         outLocation.y = (int) mLastTouchPoint.y;
     }
 
+    public int getLastTouchSource() {
+        return mLastTouchSource;
+    }
+
     public void setDragFocus(View newDragTarget) {
         if (mCurrentDragView != newDragTarget) {
             mCurrentDragView = newDragTarget;
@@ -6383,6 +6408,16 @@
         mHandler.sendMessage(msg);
     }
 
+    public void updatePointerIcon(float x, float y) {
+        final int what = MSG_UPDATE_POINTER_ICON;
+        mHandler.removeMessages(what);
+        final long now = SystemClock.uptimeMillis();
+        final MotionEvent event = MotionEvent.obtain(
+                0, now, MotionEvent.ACTION_HOVER_MOVE, x, y, 0);
+        Message msg = mHandler.obtainMessage(what, event);
+        mHandler.sendMessage(msg);
+    }
+
     public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
             int localValue, int localChanges) {
         SystemUiVisibilityInfo args = new SystemUiVisibilityInfo();
@@ -6694,16 +6729,19 @@
 
     @Override
     public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
+        if (rectangle == null) {
+            return scrollToRectOrFocus(null, immediate);
+        }
+        rectangle.offset(child.getLeft() - child.getScrollX(),
+                child.getTop() - child.getScrollY());
         final boolean scrolled = scrollToRectOrFocus(rectangle, immediate);
-        if (rectangle != null) {
-            mTempRect.set(rectangle);
-            mTempRect.offset(0, -mCurScrollY);
-            mTempRect.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
-            try {
-                mWindowSession.onRectangleOnScreenRequested(mWindow, mTempRect);
-            } catch (RemoteException re) {
-                /* ignore */
-            }
+        mTempRect.set(rectangle);
+        mTempRect.offset(0, -mCurScrollY);
+        mTempRect.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
+        try {
+            mWindowSession.onRectangleOnScreenRequested(mWindow, mTempRect);
+        } catch (RemoteException re) {
+            /* ignore */
         }
         return scrolled;
     }
@@ -6961,6 +6999,14 @@
         }
 
         @Override
+        public void updatePointerIcon(float x, float y) {
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
+            if (viewAncestor != null) {
+                viewAncestor.updatePointerIcon(x, y);
+            }
+        }
+
+        @Override
         public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
                 int localValue, int localChanges) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index dfe0cc7..ee70891 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;
@@ -794,6 +795,40 @@
         return mCallback;
     }
 
+    /**
+     * 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) {
+        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 (fso.isRegistered()) {
+            throw new IllegalStateException("FrameStatsObserver already registered on a Window.");
+        }
+
+        decorView.addFrameStatsObserver(fso);
+    }
+
+    /**
+     * Remove observer and stop listening to frame stats for this window.
+     * @hide
+     */
+    public final void removeFrameStatsObserver(FrameStatsObserver fso) {
+        final View decorView = getDecorView();
+        if (decorView != null) {
+            getDecorView().removeFrameStatsObserver(fso);
+        }
+    }
+
     /** @hide */
     public final void setOnWindowDismissedCallback(OnWindowDismissedCallback dcb) {
         mOnWindowDismissedCallback = dcb;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6c2c956..df84970 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1036,6 +1036,7 @@
             mChoiceActionMode = startActionMode(mMultiChoiceModeCallback);
         }
 
+        final boolean itemCheckChanged;
         if (mChoiceMode == CHOICE_MODE_MULTIPLE || mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
             boolean oldValue = mCheckStates.get(position);
             mCheckStates.put(position, value);
@@ -1046,7 +1047,8 @@
                     mCheckedIdStates.delete(mAdapter.getItemId(position));
                 }
             }
-            if (oldValue != value) {
+            itemCheckChanged = oldValue != value;
+            if (itemCheckChanged) {
                 if (value) {
                     mCheckedItemCount++;
                 } else {
@@ -1062,6 +1064,7 @@
             boolean updateIds = mCheckedIdStates != null && mAdapter.hasStableIds();
             // Clear all values if we're checking something, or unchecking the currently
             // selected item
+            itemCheckChanged = isItemChecked(position) != value;
             if (value || isItemChecked(position)) {
                 mCheckStates.clear();
                 if (updateIds) {
@@ -1081,8 +1084,8 @@
             }
         }
 
-        // Do not generate a data change while we are in the layout phase
-        if (!mInLayout && !mBlockLayoutRequests) {
+        // Do not generate a data change while we are in the layout phase or data has not changed
+        if (!mInLayout && !mBlockLayoutRequests && itemCheckChanged) {
             mDataChanged = true;
             rememberSyncState();
             requestLayout();
@@ -3701,6 +3704,13 @@
         }
     }
 
+    /** @hide */
+    @Override
+    protected boolean handleScrollBarDragging(MotionEvent event) {
+        // Doesn't support normal scroll bar dragging. Use FastScroller.
+        return false;
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         if (!isEnabled()) {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 4355eb3..617d3dd 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -77,6 +77,7 @@
 import android.view.ContextMenu;
 import android.view.DisplayListCanvas;
 import android.view.DragEvent;
+import android.view.DropPermissions;
 import android.view.Gravity;
 import android.view.InputDevice;
 import android.view.LayoutInflater;
@@ -1082,6 +1083,20 @@
         return true;
     }
 
+    private void startDragAndDrop() {
+        final int start = mTextView.getSelectionStart();
+        final int end = mTextView.getSelectionEnd();
+        CharSequence selectedText = mTextView.getTransformedText(start, end);
+        ClipData data = ClipData.newPlainText(null, selectedText);
+        DragLocalState localState = new DragLocalState(mTextView, start, end);
+        mTextView.startDragAndDrop(data, getTextThumbnailBuilder(selectedText), localState,
+                View.DRAG_FLAG_GLOBAL);
+        stopTextActionMode();
+        if (hasSelectionController()) {
+            getSelectionController().resetTouchOffsets();
+        }
+    }
+
     public boolean performLongClick(boolean handled) {
         // Long press in empty space moves cursor and starts the insertion action mode.
         if (!handled && !isPositionOnText(mLastDownPositionX, mLastDownPositionY) &&
@@ -1097,15 +1112,7 @@
 
         if (!handled && mTextActionMode != null) {
             if (touchPositionIsInSelection()) {
-                // Start a drag
-                final int start = mTextView.getSelectionStart();
-                final int end = mTextView.getSelectionEnd();
-                CharSequence selectedText = mTextView.getTransformedText(start, end);
-                ClipData data = ClipData.newPlainText(null, selectedText);
-                DragLocalState localState = new DragLocalState(mTextView, start, end);
-                mTextView.startDrag(data, getTextThumbnailBuilder(selectedText), localState,
-                        View.DRAG_FLAG_GLOBAL);
-                stopTextActionMode();
+                startDragAndDrop();
             } else {
                 stopTextActionMode();
                 selectCurrentWordAndStartDrag();
@@ -2292,11 +2299,24 @@
 
     void onDrop(DragEvent event) {
         StringBuilder content = new StringBuilder("");
-        ClipData clipData = event.getClipData();
-        final int itemCount = clipData.getItemCount();
-        for (int i=0; i < itemCount; i++) {
-            Item item = clipData.getItemAt(i);
-            content.append(item.coerceToStyledText(mTextView.getContext()));
+
+        final DropPermissions dropPermissions = DropPermissions.obtain(event);
+        if (dropPermissions != null) {
+            dropPermissions.takeTransient();
+        }
+
+        try {
+            ClipData clipData = event.getClipData();
+            final int itemCount = clipData.getItemCount();
+            for (int i=0; i < itemCount; i++) {
+                Item item = clipData.getItemAt(i);
+                content.append(item.coerceToStyledText(mTextView.getContext()));
+            }
+        }
+        finally {
+            if (dropPermissions != null) {
+                dropPermissions.release();
+            }
         }
 
         final int offset = mTextView.getOffsetForPosition(event.getX(), event.getY());
@@ -4925,6 +4945,14 @@
 
                     if (isMouse && !isDragAcceleratorActive()) {
                         final int offset = mTextView.getOffsetForPosition(eventX, eventY);
+                        if (mTextView.hasSelection()
+                                && (!mHaventMovedEnoughToStartDrag || mStartOffset != offset)
+                                && offset >= mTextView.getSelectionStart()
+                                && offset <= mTextView.getSelectionEnd()) {
+                            startDragAndDrop();
+                            break;
+                        }
+
                         if (mStartOffset != offset) {
                             // Start character based drag accelerator.
                             if (mTextActionMode != null) {
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index ebc7eb3..f16fdd6 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -454,6 +454,10 @@
             return true;
         }
 
+        if (super.onInterceptTouchEvent(ev)) {
+            return true;
+        }
+
         switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_MOVE: {
                 /*
diff --git a/core/java/android/widget/ScrollBarDrawable.java b/core/java/android/widget/ScrollBarDrawable.java
index 91d6232..8880217 100644
--- a/core/java/android/widget/ScrollBarDrawable.java
+++ b/core/java/android/widget/ScrollBarDrawable.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import com.android.internal.widget.ScrollBarUtils;
+
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.PixelFormat;
@@ -135,23 +137,15 @@
         }
 
         if (drawThumb) {
-            final int size = vertical ? r.height() : r.width();
+            final int scrollBarLength = vertical ? r.height() : r.width();
             final int thickness = vertical ? r.width() : r.height();
-            final int minLength = thickness * 2;
+            final int thumbLength =
+                    ScrollBarUtils.getThumbLength(scrollBarLength, thickness, extent, range);
+            final int thumbOffset =
+                    ScrollBarUtils.getThumbOffset(scrollBarLength, thumbLength, extent, range,
+                            mOffset);
 
-            // Avoid the tiny thumb.
-            int length = Math.round((float) size * extent / range);
-            if (length < minLength) {
-                length = minLength;
-            }
-
-            // Avoid the too-big thumb.
-            int offset = Math.round((float) (size - length) * mOffset / (range - extent));
-            if (offset > size - length) {
-                offset = size - length;
-            }
-
-            drawThumb(canvas, r, offset, length, vertical);
+            drawThumb(canvas, r, thumbOffset, thumbLength, vertical);
         }
     }
 
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 78b931d..3f7a07b 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -489,6 +489,10 @@
             return true;
         }
 
+        if (super.onInterceptTouchEvent(ev)) {
+            return true;
+        }
+
         /*
          * Don't try to intercept touch if we can't scroll anyway.
          */
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index b7b7400..2733391 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -66,6 +66,7 @@
 import android.widget.ListView;
 import com.android.internal.R;
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -209,7 +210,7 @@
         super.onCreate(savedInstanceState, target, title, defaultTitleRes, initialIntents,
                 null, false);
 
-        MetricsLogger.action(this, MetricsLogger.ACTION_ACTIVITY_CHOOSER_SHOWN);
+        MetricsLogger.action(this, MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN);
     }
 
     @Override
@@ -349,14 +350,14 @@
             int value = which;
             switch (mChooserListAdapter.getPositionTargetType(which)) {
                 case ChooserListAdapter.TARGET_CALLER:
-                    cat = MetricsLogger.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET;
+                    cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET;
                     break;
                 case ChooserListAdapter.TARGET_SERVICE:
-                    cat = MetricsLogger.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET;
+                    cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET;
                     value -= mChooserListAdapter.getCallerTargetCount();
                     break;
                 case ChooserListAdapter.TARGET_STANDARD:
-                    cat = MetricsLogger.ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET;
+                    cat = MetricsEvent.ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET;
                     value -= mChooserListAdapter.getCallerTargetCount()
                             + mChooserListAdapter.getServiceTargetCount();
                     break;
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 3b9b8db..ec53a2e 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -121,4 +121,7 @@
     void setBatteryState(int status, int health, int plugType, int level, int temp, int volt);
     long getAwakeTimeBattery();
     long getAwakeTimePlugged();
+
+    void noteBleScanStarted(in WorkSource ws);
+    void noteBleScanStopped(in WorkSource ws);
 }
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
new file mode 100644
index 0000000..9de4a6c
--- /dev/null
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.os.ParcelUuid;
+
+/**
+ * Service interface for a generic sound recognition model.
+ * @hide
+ */
+interface ISoundTriggerService {
+
+
+    SoundTrigger.GenericSoundModel getSoundModel(in ParcelUuid soundModelId);
+
+    void updateSoundModel(in SoundTrigger.GenericSoundModel soundModel);
+
+    void deleteSoundModel(in ParcelUuid soundModelId);
+
+    void startRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);
+
+    /**
+     * Stops recognition.
+     */
+    void stopRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);
+}
diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java
index 5ac786a..71c2c21 100644
--- a/core/java/com/android/internal/app/LocaleHelper.java
+++ b/core/java/com/android/internal/app/LocaleHelper.java
@@ -24,7 +24,7 @@
 import java.util.Locale;
 
 /**
- * This class implements some handy methods to proces with locales.
+ * This class implements some handy methods to process with locales.
  */
 public class LocaleHelper {
 
@@ -55,7 +55,7 @@
      *       source, breakIterator, UCharacter.TITLECASE_NO_LOWERCASE);
      * }}
      *
-     * <p>That also means creating BreakIteratos for each locale. Expensive...</p>
+     * <p>That also means creating a BreakIterator for each locale. Expensive...</p>
      *
      * @param str the string to sentence-case.
      * @param locale the locale used for the case conversion.
@@ -180,7 +180,7 @@
      *
      * <p>Gives priority to suggested locales (to sort them at the top).</p>
      */
-    static final class LocaleInfoComparator implements Comparator<LocaleStore.LocaleInfo> {
+    public static final class LocaleInfoComparator implements Comparator<LocaleStore.LocaleInfo> {
         private final Collator mCollator;
 
         /**
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index 2191c58..210adce 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -179,6 +179,34 @@
         return result;
     }
 
+    /*
+     * This method is added for SetupWizard, to force an update of the suggested locales
+     * when the SIM is initialized.
+     *
+     * <p>When the device is freshly started, it sometimes gets to the language selection
+     * before the SIM is properly initialized.
+     * So at the time the cache is filled, the info from the SIM might not be available.
+     * The SetupWizard has a SimLocaleMonitor class to detect onSubscriptionsChanged events.
+     * SetupWizard will call this function when that happens.</p>
+     *
+     * <p>TODO: decide if it is worth moving such kind of monitoring in this shared code.
+     * The user might change the SIM or might cross border and connect to a network
+     * in a different country, without restarting the Settings application or the phone.</p>
+     */
+    public static void updateSimCountries(Context context) {
+        Set<String> simCountries = getSimCountries(context);
+
+        for (LocaleInfo li : sLocaleCache.values()) {
+            // This method sets the suggestion flags for the (new) SIM locales, but it does not
+            // try to clean up the old flags. After all, if the user replaces a German SIM
+            // with a French one, it is still possible that they are speaking German.
+            // So both French and German are reasonable suggestions.
+            if (simCountries.contains(li.getLocale().getCountry())) {
+                li.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SIM;
+            }
+        }
+    }
+
     public static void fillCache(Context context) {
         if (sFullyInitialized) {
             return;
@@ -242,11 +270,11 @@
     /**
      * Returns a list of locales for language or region selection.
      * If the parent is null, then it is the language list.
-     * If it is not null, then the list will contain all the locales that belong to that perent.
+     * If it is not null, then the list will contain all the locales that belong to that parent.
      * Example: if the parent is "ar", then the region list will contain all Arabic locales.
      * (this is not language based, but language-script, so that it works for zh-Hant and so on.
      */
-    /* package */ static Set<LocaleInfo> getLevelLocales(Context context, Set<String> ignorables,
+    public static Set<LocaleInfo> getLevelLocales(Context context, Set<String> ignorables,
             LocaleInfo parent, boolean translatedOnly) {
         fillCache(context);
         String parentId = parent == null ? null : parent.getId();
diff --git a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
index 2f855c6..c4ec714 100644
--- a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
+++ b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
@@ -45,7 +45,7 @@
  * countries for all the other German locales, but not Switzerland
  * (Austria, Belgium, Germany, Liechtenstein, Luxembourg)</p>
  */
-class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
+public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
     private static final int TYPE_HEADER_SUGGESTED = 0;
     private static final int TYPE_HEADER_ALL_OTHERS = 1;
     private static final int TYPE_LOCALE = 2;
@@ -56,7 +56,7 @@
     private final boolean mCountryMode;
     private LayoutInflater mInflater;
 
-    SuggestedLocaleAdapter(Set<LocaleStore.LocaleInfo> localeOptions, boolean countryMode) {
+    public SuggestedLocaleAdapter(Set<LocaleStore.LocaleInfo> localeOptions, boolean countryMode) {
         mCountryMode = countryMode;
         mLocaleOptions = new ArrayList<>(localeOptions.size());
         for (LocaleStore.LocaleInfo li : localeOptions) {
@@ -169,11 +169,14 @@
         return convertView;
     }
 
-
     private boolean showHeaders() {
         return mSuggestionCount != 0 && mSuggestionCount != mLocaleOptions.size();
     }
 
+    /**
+     * Sorts the items in the adapter using a locale-aware comparator.
+     * @param comp The locale-aware comparator to use.
+     */
     public void sort(LocaleHelper.LocaleInfoComparator comp) {
         Collections.sort(mLocaleOptions, comp);
     }
@@ -222,7 +225,7 @@
 
         // TODO: decide if this is enough, or we want to use a BreakIterator...
         boolean wordMatches(String valueText, String prefixString) {
-            // First match against the whole, non-splitted value
+            // First match against the whole, non-split value
             if (valueText.startsWith(prefixString)) {
                 return true;
             }
@@ -239,7 +242,6 @@
         }
 
         @Override
-        @SuppressWarnings("unchecked")
         protected void publishResults(CharSequence constraint, FilterResults results) {
             mLocaleOptions = (ArrayList<LocaleStore.LocaleInfo>) results.values;
 
diff --git a/core/java/com/android/internal/app/UnlaunchableAppActivity.java b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
new file mode 100644
index 0000000..aada6e3
--- /dev/null
+++ b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import com.android.internal.R;
+
+/**
+ * A dialog shown to the user when they try to launch an app from a quiet profile
+ * ({@link UserManager#isQuietModeEnabled(UserHandle)}, or when the app is suspended by the
+ * profile owner or device owner.
+ */
+public class UnlaunchableAppActivity extends Activity
+        implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
+    private static final String TAG = "UnlaunchableAppActivity";
+
+    private static final int UNLAUNCHABLE_REASON_QUIET_MODE = 1;
+    private static final int UNLAUNCHABLE_REASON_SUSPENDED_PACKAGE = 2;
+    private static final String EXTRA_UNLAUNCHABLE_REASON = "unlaunchable_reason";
+
+    private int mUserId;
+    private int mReason;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = getIntent();
+        mReason = intent.getIntExtra(EXTRA_UNLAUNCHABLE_REASON, -1);
+        mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+
+        if (mUserId == UserHandle.USER_NULL) {
+            Log.wtf(TAG, "Invalid user id: " + mUserId + ". Stopping.");
+            finish();
+            return;
+        }
+
+        String dialogTitle;
+        String dialogMessage;
+        if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE) {
+            dialogTitle = getResources().getString(R.string.work_mode_off_title);
+            dialogMessage = getResources().getString(R.string.work_mode_off_message);
+        } else if (mReason == UNLAUNCHABLE_REASON_SUSPENDED_PACKAGE) {
+            PackageManager pm = getPackageManager();
+            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
+                    Context.DEVICE_POLICY_SERVICE);
+            String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+            String packageLabel = packageName;
+            try {
+                Context userContext = createPackageContextAsUser(packageName, 0,
+                        UserHandle.of(mUserId));
+                ApplicationInfo appInfo = userContext.getApplicationInfo();
+                if (appInfo != null) {
+                    packageLabel = userContext.getPackageManager().getApplicationLabel(appInfo)
+                            .toString();
+                }
+            } catch (NameNotFoundException e) {
+            }
+            dialogTitle = String.format(getResources().getString(R.string.suspended_package_title),
+                    packageLabel);
+            dialogMessage = dpm.getShortSupportMessageForUser(dpm.getProfileOwnerAsUser(mUserId),
+                    mUserId);
+            if (dialogMessage == null) {
+                dialogMessage = String.format(
+                        getResources().getString(R.string.suspended_package_message),
+                        dpm.getProfileOwnerNameAsUser(mUserId));
+            }
+        } else {
+            Log.wtf(TAG, "Invalid unlaunchable type: " + mReason);
+            finish();
+            return;
+        }
+
+        View rootView = LayoutInflater.from(this).inflate(R.layout.unlaunchable_app_activity, null);
+        TextView titleView = (TextView)rootView.findViewById(R.id.unlaunchable_app_title);
+        TextView messageView = (TextView)rootView.findViewById(R.id.unlaunchable_app_message);
+        titleView.setText(dialogTitle);
+        messageView.setText(dialogMessage);
+
+        AlertDialog.Builder builder = new AlertDialog.Builder(this)
+                .setView(rootView)
+                .setOnDismissListener(this);
+        if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE) {
+            builder.setPositiveButton(R.string.work_mode_turn_on, this)
+                    .setNegativeButton(R.string.cancel, null);
+        } else {
+            builder.setPositiveButton(R.string.ok, null);
+        }
+        builder.show();
+    }
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        finish();
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        if (mReason == UNLAUNCHABLE_REASON_QUIET_MODE && which == DialogInterface.BUTTON_POSITIVE) {
+            UserManager.get(this).setQuietModeEnabled(mUserId, false);
+        }
+    }
+
+    private static final Intent createBaseIntent() {
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName("android", UnlaunchableAppActivity.class.getName()));
+        intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        return intent;
+    }
+
+    public static Intent createInQuietModeDialogIntent(int userId) {
+        Intent intent = createBaseIntent();
+        intent.putExtra(EXTRA_UNLAUNCHABLE_REASON, UNLAUNCHABLE_REASON_QUIET_MODE);
+        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+        return intent;
+    }
+
+    public static Intent createPackageSuspendedDialogIntent(String packageName, int userId) {
+        Intent intent = createBaseIntent();
+        intent.putExtra(EXTRA_UNLAUNCHABLE_REASON, UNLAUNCHABLE_REASON_SUSPENDED_PACKAGE);
+        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
+        return intent;
+    }
+}
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index 444dbfa..98f5bea 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -249,6 +249,16 @@
      */
     boolean isAppEligibleForBackup(in PackageInfo targetPackage, boolean isFullBackup);
 
+    /**
+     * Ask the transport about current quota for backup size of the package.
+     *
+     * @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.
+     */
+    long getBackupQuota(String packageName, boolean isFullBackup);
+
     // full restore stuff
 
     /**
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 22d35f2..8cdfc64 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -71,6 +71,9 @@
     // The currently-active restore set always has the same (nonzero!) token
     private static final long CURRENT_SET_TOKEN = 1;
 
+    // Full backup size quota is set to reasonable value.
+    private static final long FULL_BACKUP_SIZE_QUOTA = 25 * 1024 * 1024;
+
     private Context mContext;
     private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup");
     private File mCurrentSetDir = new File(mDataDir, Long.toString(CURRENT_SET_TOKEN));
@@ -90,6 +93,7 @@
     private FileInputStream mSocketInputStream;
     private BufferedOutputStream mFullBackupOutputStream;
     private byte[] mFullBackupBuffer;
+    private long mFullBackupSize;
 
     private FileInputStream mCurFullRestoreStream;
     private FileOutputStream mFullRestoreSocketStream;
@@ -314,8 +318,13 @@
 
     @Override
     public int checkFullBackupSize(long size) {
+        int result = TRANSPORT_OK;
         // Decline zero-size "backups"
-        final int result = (size > 0) ? TRANSPORT_OK : TRANSPORT_PACKAGE_REJECTED;
+        if (size <= 0) {
+            result = TRANSPORT_PACKAGE_REJECTED;
+        } else if (size > FULL_BACKUP_SIZE_QUOTA) {
+            result = TRANSPORT_QUOTA_EXCEEDED;
+        }
         if (result != TRANSPORT_OK) {
             if (DEBUG) {
                 Log.v(TAG, "Declining backup of size " + size);
@@ -339,6 +348,7 @@
         // sure to dup() our own copy of the socket fd.  Transports which run in
         // their own processes must not do this.
         try {
+            mFullBackupSize = 0;
             mSocket = ParcelFileDescriptor.dup(socket.getFileDescriptor());
             mSocketInputStream = new FileInputStream(mSocket.getFileDescriptor());
         } catch (IOException e) {
@@ -359,6 +369,11 @@
             return TRANSPORT_ERROR;
         }
 
+        mFullBackupSize += numBytes;
+        if (mFullBackupSize > FULL_BACKUP_SIZE_QUOTA) {
+            return TRANSPORT_QUOTA_EXCEEDED;
+        }
+
         if (numBytes > mFullBackupBuffer.length) {
             mFullBackupBuffer = new byte[numBytes];
         }
@@ -699,4 +714,8 @@
         return TRANSPORT_OK;
     }
 
+    @Override
+    public long getBackupQuota(String packageName, boolean isFullBackup) {
+        return isFullBackup ? FULL_BACKUP_SIZE_QUOTA : Long.MAX_VALUE;
+    }
 }
diff --git a/core/java/com/android/internal/logging/MetricsConstants.java b/core/java/com/android/internal/logging/MetricsConstants.java
deleted file mode 100644
index 37bf71c..0000000
--- a/core/java/com/android/internal/logging/MetricsConstants.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.logging;
-
-/**
- * Constants for mestrics logs.
- *
- * @hide
- */
-public interface MetricsConstants {
-    // These constants must match those in the analytic pipeline, do not edit.
-    // Add temporary values to the top of MetricsLogger instead.
-    public static final int VIEW_UNKNOWN = 0;
-    public static final int MAIN_SETTINGS = 1;
-    public static final int ACCESSIBILITY = 2;
-    public static final int ACCESSIBILITY_CAPTION_PROPERTIES = 3;
-    public static final int ACCESSIBILITY_SERVICE = 4;
-    public static final int ACCESSIBILITY_TOGGLE_DALTONIZER = 5;
-    public static final int ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6;
-    public static final int ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7;
-    public static final int ACCOUNT = 8;
-    public static final int ACCOUNTS_ACCOUNT_SYNC = 9;
-    public static final int ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10;
-    public static final int ACCOUNTS_MANAGE_ACCOUNTS = 11;
-    public static final int APN = 12;
-    public static final int APN_EDITOR = 13;
-    public static final int APP_OPS_DETAILS = 14;
-    public static final int APP_OPS_SUMMARY = 15;
-    public static final int APPLICATION = 16;
-    public static final int APPLICATIONS_APP_LAUNCH = 17;
-    public static final int APPLICATIONS_APP_PERMISSION = 18;
-    public static final int APPLICATIONS_APP_STORAGE = 19;
-    public static final int APPLICATIONS_INSTALLED_APP_DETAILS = 20;
-    public static final int APPLICATIONS_PROCESS_STATS_DETAIL = 21;
-    public static final int APPLICATIONS_PROCESS_STATS_MEM_DETAIL = 22;
-    public static final int APPLICATIONS_PROCESS_STATS_UI = 23;
-    public static final int BLUETOOTH = 24;
-    public static final int BLUETOOTH_DEVICE_PICKER = 25;
-    public static final int BLUETOOTH_DEVICE_PROFILES = 26;
-    public static final int CHOOSE_LOCK_GENERIC = 27;
-    public static final int CHOOSE_LOCK_PASSWORD = 28;
-    public static final int CHOOSE_LOCK_PATTERN = 29;
-    public static final int CONFIRM_LOCK_PASSWORD = 30;
-    public static final int CONFIRM_LOCK_PATTERN = 31;
-    public static final int CRYPT_KEEPER = 32;
-    public static final int CRYPT_KEEPER_CONFIRM = 33;
-    public static final int DASHBOARD_SEARCH_RESULTS = 34;
-    public static final int DASHBOARD_SUMMARY = 35;
-    public static final int DATA_USAGE = 36;
-    public static final int DATA_USAGE_SUMMARY = 37;
-    public static final int DATE_TIME = 38;
-    public static final int DEVELOPMENT = 39;
-    public static final int DEVICEINFO = 40;
-    public static final int DEVICEINFO_IMEI_INFORMATION = 41;
-    public static final int DEVICEINFO_MEMORY = 42;
-    public static final int DEVICEINFO_SIM_STATUS = 43;
-    public static final int DEVICEINFO_STATUS = 44;
-    public static final int DEVICEINFO_USB = 45;
-    public static final int DISPLAY = 46;
-    public static final int DREAM = 47;
-    public static final int ENCRYPTION = 48;
-    public static final int FINGERPRINT = 49;
-    public static final int FINGERPRINT_ENROLL = 50;
-    public static final int FUELGAUGE_BATTERY_HISTORY_DETAIL = 51;
-    public static final int FUELGAUGE_BATTERY_SAVER = 52;
-    public static final int FUELGAUGE_POWER_USAGE_DETAIL = 53;
-    public static final int FUELGAUGE_POWER_USAGE_SUMMARY = 54;
-    public static final int HOME = 55;
-    public static final int ICC_LOCK = 56;
-    public static final int INPUTMETHOD_LANGUAGE = 57;
-    public static final int INPUTMETHOD_KEYBOARD = 58;
-    public static final int INPUTMETHOD_SPELL_CHECKERS = 59;
-    public static final int INPUTMETHOD_SUBTYPE_ENABLER = 60;
-    public static final int INPUTMETHOD_USER_DICTIONARY = 61;
-    public static final int INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62;
-    public static final int LOCATION = 63;
-    public static final int LOCATION_MODE = 64;
-    public static final int MANAGE_APPLICATIONS = 65;
-    public static final int MASTER_CLEAR = 66;
-    public static final int MASTER_CLEAR_CONFIRM = 67;
-    public static final int NET_DATA_USAGE_METERED = 68;
-    public static final int NFC_BEAM = 69;
-    public static final int NFC_PAYMENT = 70;
-    public static final int NOTIFICATION = 71;
-    public static final int NOTIFICATION_APP_NOTIFICATION = 72;
-    public static final int NOTIFICATION_OTHER_SOUND = 73;
-    public static final int NOTIFICATION_REDACTION = 74;
-    public static final int NOTIFICATION_STATION = 75;
-    public static final int NOTIFICATION_ZEN_MODE = 76;
-    public static final int OWNER_INFO = 77;
-    public static final int PRINT_JOB_SETTINGS = 78;
-    public static final int PRINT_SERVICE_SETTINGS = 79;
-    public static final int PRINT_SETTINGS = 80;
-    public static final int PRIVACY = 81;
-    public static final int PROXY_SELECTOR = 82;
-    public static final int RESET_NETWORK = 83;
-    public static final int RESET_NETWORK_CONFIRM = 84;
-    public static final int RUNNING_SERVICE_DETAILS = 85;
-    public static final int SCREEN_PINNING = 86;
-    public static final int SECURITY = 87;
-    public static final int SIM = 88;
-    public static final int TESTING = 89;
-    public static final int TETHER = 90;
-    public static final int TRUST_AGENT = 91;
-    public static final int TRUSTED_CREDENTIALS = 92;
-    public static final int TTS_ENGINE_SETTINGS = 93;
-    public static final int TTS_TEXT_TO_SPEECH = 94;
-    public static final int USAGE_ACCESS = 95;
-    public static final int USER = 96;
-    public static final int USERS_APP_RESTRICTIONS = 97;
-    public static final int USER_DETAILS = 98;
-    public static final int VOICE_INPUT = 99;
-    public static final int VPN = 100;
-    public static final int WALLPAPER_TYPE = 101;
-    public static final int WFD_WIFI_DISPLAY = 102;
-    public static final int WIFI = 103;
-    public static final int WIFI_ADVANCED = 104;
-    public static final int WIFI_CALLING = 105;
-    public static final int WIFI_SAVED_ACCESS_POINTS = 106;
-    public static final int WIFI_APITEST = 107;
-    public static final int WIFI_INFO = 108;
-    public static final int WIFI_P2P = 109;
-    public static final int WIRELESS = 110;
-    public static final int QS_PANEL = 111;
-    public static final int QS_AIRPLANEMODE = 112;
-    public static final int QS_BLUETOOTH = 113;
-    public static final int QS_CAST = 114;
-    public static final int QS_CELLULAR = 115;
-    public static final int QS_COLORINVERSION = 116;
-    public static final int QS_DATAUSAGEDETAIL = 117;
-    public static final int QS_DND = 118;
-    public static final int QS_FLASHLIGHT = 119;
-    public static final int QS_HOTSPOT = 120;
-    public static final int QS_INTENT = 121;
-    public static final int QS_LOCATION = 122;
-    public static final int QS_ROTATIONLOCK = 123;
-    public static final int QS_USERDETAILITE = 124;
-    public static final int QS_USERDETAIL = 125;
-    public static final int QS_WIFI = 126;
-    public static final int NOTIFICATION_PANEL = 127;
-    public static final int NOTIFICATION_ITEM = 128;
-    public static final int NOTIFICATION_ITEM_ACTION = 129;
-    public static final int APPLICATIONS_ADVANCED = 130;
-    public static final int LOCATION_SCANNING = 131;
-    public static final int MANAGE_APPLICATIONS_ALL = 132;
-    public static final int MANAGE_APPLICATIONS_NOTIFICATIONS = 133;
-    public static final int ACTION_WIFI_ADD_NETWORK = 134;
-    public static final int ACTION_WIFI_CONNECT = 135;
-    public static final int ACTION_WIFI_FORCE_SCAN = 136;
-    public static final int ACTION_WIFI_FORGET = 137;
-    public static final int ACTION_WIFI_OFF = 138;
-    public static final int ACTION_WIFI_ON = 139;
-    public static final int MANAGE_PERMISSIONS = 140;
-    public static final int NOTIFICATION_ZEN_MODE_PRIORITY = 141;
-    public static final int NOTIFICATION_ZEN_MODE_AUTOMATION = 142;
-    public static final int MANAGE_DOMAIN_URLS = 143;
-    public static final int NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
-    public static final int NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145;
-    public static final int NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
-    public static final int ACTION_BAN_APP_NOTES = 147;
-    public static final int ACTION_DISMISS_ALL_NOTES = 148;
-    public static final int QS_DND_DETAILS = 149;
-    public static final int QS_BLUETOOTH_DETAILS = 150;
-    public static final int QS_CAST_DETAILS = 151;
-    public static final int QS_WIFI_DETAILS = 152;
-    public static final int QS_WIFI_TOGGLE = 153;
-    public static final int QS_BLUETOOTH_TOGGLE = 154;
-    public static final int QS_CELLULAR_TOGGLE = 155;
-    public static final int QS_SWITCH_USER = 156;
-    public static final int QS_CAST_SELECT = 157;
-    public static final int QS_CAST_DISCONNECT = 158;
-    public static final int ACTION_BLUETOOTH_TOGGLE = 159;
-    public static final int ACTION_BLUETOOTH_SCAN = 160;
-    public static final int ACTION_BLUETOOTH_RENAME = 161;
-    public static final int ACTION_BLUETOOTH_FILES = 162;
-    public static final int QS_DND_TIME = 163;
-    public static final int QS_DND_CONDITION_SELECT = 164;
-    public static final int QS_DND_ZEN_SELECT = 165;
-    public static final int QS_DND_TOGGLE = 166;
-    public static final int ACTION_ZEN_ALLOW_REMINDERS = 167;
-    public static final int ACTION_ZEN_ALLOW_EVENTS = 168;
-    public static final int ACTION_ZEN_ALLOW_MESSAGES = 169;
-    public static final int ACTION_ZEN_ALLOW_CALLS = 170;
-    public static final int ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
-    public static final int ACTION_ZEN_ADD_RULE = 172;
-    public static final int ACTION_ZEN_ADD_RULE_OK = 173;
-    public static final int ACTION_ZEN_DELETE_RULE = 174;
-    public static final int ACTION_ZEN_DELETE_RULE_OK = 175;
-    public static final int ACTION_ZEN_ENABLE_RULE = 176;
-    public static final int ACTION_AIRPLANE_TOGGLE = 177;
-    public static final int ACTION_CELL_DATA_TOGGLE = 178;
-    public static final int NOTIFICATION_ACCESS = 179;
-    public static final int NOTIFICATION_ZEN_MODE_ACCESS = 180;
-    public static final int APPLICATIONS_DEFAULT_APPS = 181;
-    public static final int APPLICATIONS_STORAGE_APPS = 182;
-    public static final int APPLICATIONS_USAGE_ACCESS_DETAIL = 183;
-    public static final int APPLICATIONS_HIGH_POWER_APPS = 184;
-    public static final int FUELGAUGE_HIGH_POWER_DETAILS = 185;
-    public static final int ACTION_LS_UNLOCK = 186;
-    public static final int ACTION_LS_SHADE = 187;
-    public static final int ACTION_LS_HINT = 188;
-    public static final int ACTION_LS_CAMERA = 189;
-    public static final int ACTION_LS_DIALER = 190;
-    public static final int ACTION_LS_LOCK = 191;
-    public static final int ACTION_LS_NOTE = 192;
-    public static final int ACTION_LS_QS = 193;
-    public static final int ACTION_SHADE_QS_PULL = 194;
-    public static final int ACTION_SHADE_QS_TAP = 195;
-    public static final int LOCKSCREEN = 196;
-    public static final int BOUNCER = 197;
-    public static final int SCREEN = 198;
-    public static final int NOTIFICATION_ALERT = 199;
-    public static final int ACTION_EMERGENCY_CALL = 200;
-    public static final int APPLICATIONS_MANAGE_ASSIST = 201;
-    public static final int PROCESS_STATS_SUMMARY = 202;
-    public static final int ACTION_ROTATION_LOCK = 203;
-    public static final int ACTION_NOTE_CONTROLS = 204;
-    public static final int ACTION_NOTE_INFO = 205;
-    public static final int ACTION_APP_NOTE_SETTINGS = 206;
-    public static final int VOLUME_DIALOG = 207;
-    public static final int VOLUME_DIALOG_DETAILS = 208;
-    public static final int ACTION_VOLUME_SLIDER = 209;
-    public static final int ACTION_VOLUME_STREAM = 210;
-    public static final int ACTION_VOLUME_KEY = 211;
-    public static final int ACTION_VOLUME_ICON = 212;
-    public static final int ACTION_RINGER_MODE = 213;
-    public static final int ACTION_ACTIVITY_CHOOSER_SHOWN = 214;
-    public static final int ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET = 215;
-    public static final int ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET = 216;
-    public static final int ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET = 217;
-    public static final int ACTION_BRIGHTNESS = 218;
-    public static final int ACTION_BRIGHTNESS_AUTO = 219;
-    public static final int BRIGHTNESS_DIALOG = 220;
-    public static final int SYSTEM_ALERT_WINDOW_APPS = 221;
-    public static final int DREAMING = 222;
-    public static final int DOZING = 223;
-    public static final int OVERVIEW_ACTIVITY = 224;
-    public static final int ABOUT_LEGAL_SETTINGS = 225;
-    public static final int ACTION_SEARCH_RESULTS = 226;
-    public static final int TUNER = 227;
-    public static final int TUNER_QS = 228;
-    public static final int TUNER_DEMO_MODE = 229;
-    public static final int TUNER_QS_REORDER = 230;
-    public static final int TUNER_QS_ADD = 231;
-    public static final int TUNER_QS_REMOVE = 232;
-    public static final int TUNER_STATUS_BAR_ENABLE = 233;
-    public static final int TUNER_STATUS_BAR_DISABLE = 234;
-    public static final int TUNER_DEMO_MODE_ENABLED = 235;
-    public static final int TUNER_DEMO_MODE_ON = 236;
-    public static final int TUNER_BATTERY_PERCENTAGE = 237;
-    public static final int FUELGAUGE_INACTIVE_APPS = 238;
-    public static final int ACTION_ASSIST_LONG_PRESS = 239;
-    public static final int FINGERPRINT_ENROLLING = 240;
-    public static final int FINGERPRINT_FIND_SENSOR = 241;
-    public static final int FINGERPRINT_ENROLL_FINISH = 242;
-    public static final int FINGERPRINT_ENROLL_INTRO = 243;
-    public static final int FINGERPRINT_ENROLL_ONBOARD = 244;
-    public static final int FINGERPRINT_ENROLL_SIDECAR = 245;
-    public static final int FINGERPRINT_ENROLLING_SETUP = 246;
-    public static final int FINGERPRINT_FIND_SENSOR_SETUP = 247;
-    public static final int FINGERPRINT_ENROLL_FINISH_SETUP = 248;
-    public static final int FINGERPRINT_ENROLL_INTRO_SETUP = 249;
-    public static final int FINGERPRINT_ENROLL_ONBOARD_SETUP = 250;
-    public static final int ACTION_FINGERPRINT_ENROLL = 251;
-    public static final int ACTION_FINGERPRINT_AUTH = 252;
-    public static final int ACTION_FINGERPRINT_DELETE = 253;
-    public static final int ACTION_FINGERPRINT_RENAME = 254;
-    public static final int ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE = 255;
-    public static final int ACTION_WIGGLE_CAMERA_GESTURE = 256;
-    public static final int QS_WORKMODE = 257;
-    public static final int BACKGROUND_CHECK_SUMMARY = 258;
-
-    // These constants must match those in the analytic pipeline, do not edit.
-    // Add temporary values to the top of MetricsLogger instead.
-
-    //aliases
-    public static final int DEVICEINFO_STORAGE = DEVICEINFO_MEMORY;
-}
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index b0b25d3..ef725da 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -15,69 +15,21 @@
  */
 package com.android.internal.logging;
 
-
 import android.content.Context;
 import android.os.Build;
 import android.view.View;
 
+import com.android.internal.logging.MetricsProto.MetricsEvent;
+
 /**
  * Log all the things.
  *
  * @hide
  */
-public class MetricsLogger implements MetricsConstants {
-    // Temporary constants go here, to await migration to MetricsConstants.
-    public static final int QS_USER_TILE = 258;
-    public static final int QS_BATTERY_TILE = 259;
-    public static final int NOTIFICATION_ZEN_MODE_VISUAL_INTERRUPTIONS = 260;
-    public static final int ACTION_ZEN_ALLOW_PEEK = 261;
-    public static final int ACTION_ZEN_ALLOW_LIGHTS = 262;
-    public static final int NOTIFICATION_TOPIC_NOTIFICATION = 263;
-    public static final int ACTION_DEFAULT_SMS_APP_CHANGED = 264;
-    public static final int QS_COLOR_MATRIX = 265;
-    public static final int QS_CUSTOM = 266;
-    public static final int ACTION_ZEN_ALLOW_SCREEN_ON = 267;
+public class MetricsLogger {
+    // define metric categories in frameworks/base/proto/src/metrics_constants.proto.
 
-    /**
-     * Logged when the user docks a window from recents by longpressing a task and dragging it to
-     * the dock area.
-     */
-    public static final int ACTION_WINDOW_DOCK_DRAG_DROP = 268;
-
-    /**
-     * Logged when the user docks a fullscreen window by long pressing recents which also opens
-     * recents on the lower/right side.
-     */
-    public static final int ACTION_WINDOW_DOCK_LONGPRESS = 269;
-
-    /**
-     * Logged when the user docks a window by dragging from the navbar which also opens recents on
-     * the lower/right side.
-     */
-    public static final int ACTION_WINDOW_DOCK_SWIPE = 270;
-
-    /**
-     * Logged when the user launches a profile-specific app and we intercept it with the confirm
-     * credentials UI.
-     */
-    public static final int PROFILE_CHALLENGE = 271;
-    public static final int QS_BATTERY_DETAIL = 272;
-
-    /**
-     * Logged when the user goes into the overview history.
-     */
-    public static final int OVERVIEW_HISTORY = 273;
-
-    /**
-     * Logged when the user pages through overview.
-     */
-    public static final int ACTION_OVERVIEW_PAGE = 274;
-
-    /**
-     * Logged when the user launches a task from overview.
-     */
-    public static final int ACTION_OVERVIEW_SELECT = 275;
-
+    public static final int VIEW_UNKNOWN = MetricsEvent.VIEW_UNKNOWN;
 
     public static void visible(Context context, int category) throws IllegalArgumentException {
         if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index 5b40bc0..a572486 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -237,6 +237,22 @@
         return mMiddleTarget;
     }
 
+    public SnapTarget getNextTarget(SnapTarget snapTarget) {
+        int index = mTargets.indexOf(snapTarget);
+        if (index != -1 && index < mTargets.size() - 1) {
+            return mTargets.get(index + 1);
+        }
+        return snapTarget;
+    }
+
+    public SnapTarget getPreviousTarget(SnapTarget snapTarget) {
+        int index = mTargets.indexOf(snapTarget);
+        if (index != -1 && index > 0) {
+            return mTargets.get(index - 1);
+        }
+        return snapTarget;
+    }
+
     /**
      * Represents a snap target for the divider.
      */
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index 381e71f..2f26e92 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -42,6 +42,23 @@
      * @return the string reference that was validated
      * @throws IllegalArgumentException if {@code string} is empty
      */
+    public static @NonNull String checkStringNotEmpty(final String string) {
+        if (TextUtils.isEmpty(string)) {
+            throw new IllegalArgumentException();
+        }
+        return string;
+    }
+
+    /**
+     * Ensures that an string reference passed as a parameter to the calling
+     * method is not empty.
+     *
+     * @param string an string reference
+     * @param errorMessage the exception message to use if the check fails; will
+     *     be converted to a string using {@link String#valueOf(Object)}
+     * @return the string reference that was validated
+     * @throws IllegalArgumentException if {@code string} is empty
+     */
     public static @NonNull String checkStringNotEmpty(final String string,
             final Object errorMessage) {
         if (TextUtils.isEmpty(string)) {
@@ -301,8 +318,8 @@
      *
      * @throws NullPointerException if the {@code value} or any of its elements were {@code null}
      */
-    public static <T> Collection<T> checkCollectionElementsNotNull(final Collection<T> value,
-            final String valueName) {
+    public static @NonNull <C extends Collection<T>, T> C checkCollectionElementsNotNull(
+            final C value, final String valueName) {
         if (value == null) {
             throw new NullPointerException(valueName + " must not be null");
         }
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index aa4b564c..7dfc15d 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -86,6 +86,10 @@
     }
 
     @Override
+    public void updatePointerIcon(float x, float y) {
+    }
+
+    @Override
     public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
             int localValue, int localChanges) {
         mSeq = seq;
diff --git a/core/java/com/android/internal/view/IDropPermissions.aidl b/core/java/com/android/internal/view/IDropPermissions.aidl
index 2438bda..74ff4b4 100644
--- a/core/java/com/android/internal/view/IDropPermissions.aidl
+++ b/core/java/com/android/internal/view/IDropPermissions.aidl
@@ -24,5 +24,6 @@
  */
 interface IDropPermissions {
     void take(IBinder activityToken);
+    void takeTransient(IBinder permissionOwnerToken);
     void release();
 }
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 4e8f19c..3f468ac 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -136,6 +136,7 @@
     private static final String LOCK_SCREEN_DEVICE_OWNER_INFO = "lockscreen.device_owner_info";
 
     private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents";
+    private static final String IS_TRUST_USUALLY_MANAGED = "lockscreen.istrustusuallymanaged";
 
     private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
 
@@ -149,6 +150,30 @@
     private ILockSettings mLockSettingsService;
     private UserManager mUserManager;
 
+    /**
+     * Use {@link TrustManager#isTrustUsuallyManaged(int)}.
+     *
+     * This returns the lazily-peristed value and should only be used by TrustManagerService.
+     */
+    public boolean isTrustUsuallyManaged(int userId) {
+        if (!(mLockSettingsService instanceof ILockSettings.Stub)) {
+            throw new IllegalStateException("May only be called by TrustManagerService. "
+                    + "Use TrustManager.isTrustUsuallyManaged()");
+        }
+        try {
+            return getLockSettings().getBoolean(IS_TRUST_USUALLY_MANAGED, false, userId);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    public void setTrustUsuallyManaged(boolean managed, int userId) {
+        try {
+            getLockSettings().setBoolean(IS_TRUST_USUALLY_MANAGED, managed, userId);
+        } catch (RemoteException e) {
+            // System dead.
+        }
+    }
 
     public static final class RequestThrottledException extends Exception {
         private int mTimeoutMs;
@@ -911,6 +936,13 @@
     }
 
     /**
+     * Retrieves whether the current profile and device locks can be unified.
+     */
+    public boolean isSeparateProfileChallengeAllowedToUnify(int userHandle) {
+        return getDevicePolicyManager().isProfileActivePasswordSufficientForParent(userHandle);
+    }
+
+    /**
      * Deserialize a pattern.
      * @param string The pattern serialized with {@link #patternToString}
      * @return The pattern.
@@ -1393,25 +1425,32 @@
          */
         public static final int SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL = 0x10;
 
-        public static final int DEFAULT = STRONG_AUTH_REQUIRED_AFTER_BOOT;
-
         private static final int ALLOWING_FINGERPRINT = STRONG_AUTH_NOT_REQUIRED
                 | SOME_AUTH_REQUIRED_AFTER_USER_REQUEST
                 | SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL;
 
         private final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
         private final H mHandler;
+        private final int mDefaultStrongAuthFlags;
 
-        public StrongAuthTracker() {
-            this(Looper.myLooper());
+        public StrongAuthTracker(Context context) {
+            this(context, Looper.myLooper());
         }
 
         /**
          * @param looper the looper on whose thread calls to {@link #onStrongAuthRequiredChanged}
          *               will be scheduled.
+         * @param context the current {@link Context}
          */
-        public StrongAuthTracker(Looper looper) {
+        public StrongAuthTracker(Context context, Looper looper) {
             mHandler = new H(looper);
+            mDefaultStrongAuthFlags = getDefaultFlags(context);
+        }
+
+        public static @StrongAuthFlags int getDefaultFlags(Context context) {
+            boolean strongAuthRequired = context.getResources().getBoolean(
+                    com.android.internal.R.bool.config_strongAuthRequiredOnBoot);
+            return strongAuthRequired ? STRONG_AUTH_REQUIRED_AFTER_BOOT : STRONG_AUTH_NOT_REQUIRED;
         }
 
         /**
@@ -1422,7 +1461,7 @@
          * @param userId the user for whom the state is queried.
          */
         public @StrongAuthFlags int getStrongAuthForUser(int userId) {
-            return mStrongAuthRequiredForUser.get(userId, DEFAULT);
+            return mStrongAuthRequiredForUser.get(userId, mDefaultStrongAuthFlags);
         }
 
         /**
@@ -1452,7 +1491,7 @@
 
             int oldValue = getStrongAuthForUser(userId);
             if (strongAuthFlags != oldValue) {
-                if (strongAuthFlags == DEFAULT) {
+                if (strongAuthFlags == mDefaultStrongAuthFlags) {
                     mStrongAuthRequiredForUser.delete(userId);
                 } else {
                     mStrongAuthRequiredForUser.put(userId, strongAuthFlags);
diff --git a/core/java/com/android/internal/widget/ScrollBarUtils.java b/core/java/com/android/internal/widget/ScrollBarUtils.java
new file mode 100644
index 0000000..0ae9f74
--- /dev/null
+++ b/core/java/com/android/internal/widget/ScrollBarUtils.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 com.android.internal.widget;
+
+public class ScrollBarUtils {
+
+    public static int getThumbLength(int size, int thickness, int extent, int range) {
+        // Avoid the tiny thumb.
+        final int minLength = thickness * 2;
+        int length = Math.round((float) size * extent / range);
+        if (length < minLength) {
+            length = minLength;
+        }
+        return length;
+    }
+
+    public static int getThumbOffset(int size, int thumbLength, int extent, int range, int offset) {
+        // Avoid the too-big thumb.
+        int thumbOffset = Math.round((float) (size - thumbLength) * offset / (range - extent));
+        if (thumbOffset > size - thumbLength) {
+            thumbOffset = size - thumbLength;
+        }
+        return thumbOffset;
+    }
+}
diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java
index 3f76e13..cee98b8 100644
--- a/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -47,6 +47,7 @@
     private static final String PREFERRED_HELPER = "preferred_activities";
     private static final String NOTIFICATION_HELPER = "notifications";
     private static final String PERMISSION_HELPER = "permissions";
+    private static final String USAGE_STATS_HELPER = "usage_stats";
 
     // These paths must match what the WallpaperManagerService uses.  The leaf *_FILENAME
     // are also used in the full-backup file format, so must not change unless steps are
@@ -96,7 +97,7 @@
         addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
         addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
         addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
-
+        addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
         super.onBackup(oldState, data, newState);
     }
 
@@ -131,6 +132,7 @@
         addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
         addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
         addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
+        addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
 
         try {
             super.onRestore(data, appVersionCode, newState);
@@ -183,7 +185,7 @@
             if (restoredWallpaper) {
                 IWallpaperManager wallpaper =
                         (IWallpaperManager)ServiceManager.getService(
-                        Context.WALLPAPER_SERVICE);
+                                Context.WALLPAPER_SERVICE);
                 if (wallpaper != null) {
                     try {
                         wallpaper.settingsRestored();
diff --git a/core/java/com/android/server/backup/UsageStatsBackupHelper.java b/core/java/com/android/server/backup/UsageStatsBackupHelper.java
new file mode 100644
index 0000000..bde2396
--- /dev/null
+++ b/core/java/com/android/server/backup/UsageStatsBackupHelper.java
@@ -0,0 +1,70 @@
+package com.android.server.backup;
+
+
+import android.app.backup.BlobBackupHelper;
+import android.app.usage.IUsageStatsManager;
+import android.app.usage.UsageStatsManagerInternal;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.Log;
+
+import com.android.server.LocalServices;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class UsageStatsBackupHelper extends BlobBackupHelper {
+    static final String TAG = "UsgStatsBackupHelper";   // must be < 23 chars
+    static final boolean DEBUG = false;
+
+    // Current version of the blob schema
+    static final int BLOB_VERSION = 1;
+
+    // Key under which the payload blob is stored
+    // same as UsageStatsBackupHelperAssistant.KEY_USAGE_STATS
+    static final String KEY_USAGE_STATS = "usage_stats";
+
+    public UsageStatsBackupHelper(Context context) {
+        super(BLOB_VERSION, KEY_USAGE_STATS);
+    }
+
+    @Override
+    protected byte[] getBackupPayload(String key) {
+        if(KEY_USAGE_STATS.equals(key)) {
+            UsageStatsManagerInternal localUsageStatsManager = LocalServices.getService(UsageStatsManagerInternal.class);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            DataOutputStream out  = new DataOutputStream(baos);
+            try{
+                out.writeInt(UserHandle.USER_SYSTEM);
+                out.write(localUsageStatsManager.getBackupPayload(UserHandle.USER_SYSTEM, key));
+            } catch (IOException ioe){
+                if (DEBUG) Log.e(TAG, "Failed to backup Usage Stats", ioe);
+                baos.reset();
+            }
+            return baos.toByteArray();
+        }
+        return null;
+    }
+
+
+    @Override
+    protected void applyRestoredPayload(String key, byte[] payload)  {
+        if (KEY_USAGE_STATS.equals(key)) {
+            UsageStatsManagerInternal localUsageStatsManager = LocalServices.getService(UsageStatsManagerInternal.class);
+            DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload));
+            try{
+                int user = in.readInt();
+                byte[] restoreData = new byte[payload.length - 4];
+                in.read(restoreData, 0, payload.length-4);
+                localUsageStatsManager.applyRestoredPayload(user, key, restoreData);
+            } catch (IOException ioe){
+                if (DEBUG) Log.e(TAG, "Failed to restore Usage Stats", ioe);
+            }
+        }
+    }
+}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 644ecc6..8c4683d 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -176,7 +176,8 @@
     com_android_internal_net_NetworkStatsFactory.cpp \
     com_android_internal_os_Zygote.cpp \
     com_android_internal_util_VirtualRefBasePtr.cpp \
-    com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
+    com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp \
+    android_os_HardwarePropertiesManager.cpp
 
 LOCAL_C_INCLUDES += \
     $(JNI_H_INCLUDE) \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 321440c..2e45f8c 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -197,6 +197,7 @@
 extern int register_com_android_internal_net_NetworkStatsFactory(JNIEnv *env);
 extern int register_com_android_internal_os_Zygote(JNIEnv *env);
 extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
+extern int register_android_os_HardwarePropertiesManager(JNIEnv *env);
 
 static AndroidRuntime* gCurRuntime = NULL;
 
@@ -1387,7 +1388,7 @@
     REG_JNI(register_android_animation_PropertyValuesHolder),
     REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
     REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
-
+    REG_JNI(register_android_os_HardwarePropertiesManager),
 
 };
 
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 61dc6e4..2018e76 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -18,6 +18,8 @@
 
 #include <stdio.h>
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
@@ -34,6 +36,8 @@
 
 // ----------------------------------------------------------------------------
 
+#define EGL_QCOM_PROTECTED_CONTENT 0x32E0
+
 namespace android {
 
 static const char* const OutOfResourcesException =
@@ -55,6 +59,28 @@
     return android_atomic_inc(&globalCounter);
 }
 
+// Check whether the current EGL context is protected.
+static bool isProtectedContext() {
+    EGLDisplay dpy = eglGetCurrentDisplay();
+    EGLContext ctx = eglGetCurrentContext();
+
+    if (dpy == EGL_NO_DISPLAY) {
+        ALOGE("isProtectedSurface: invalid current EGLDisplay");
+        return false;
+    }
+
+    if (ctx == EGL_NO_CONTEXT) {
+        ALOGE("isProtectedSurface: invalid current EGLContext");
+        return false;
+    }
+
+    EGLint isProtected = EGL_FALSE;
+    // TODO: Change the enum value below when an extension is ratified.
+    eglQueryContext(dpy, ctx, EGL_QCOM_PROTECTED_CONTENT, &isProtected);
+
+    return isProtected;
+}
+
 // ----------------------------------------------------------------------------
 
 static void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz,
@@ -263,6 +289,11 @@
             getpid(),
             createProcessUniqueId()));
 
+    // If the current context is protected, inform the producer.
+    if (isProtectedContext()) {
+        consumer->setConsumerUsageBits(GRALLOC_USAGE_PROTECTED);
+    }
+
     SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
     SurfaceTexture_setProducer(env, thiz, producer);
 
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 34877e0..35b5016 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -86,20 +86,20 @@
 }
 
 static jint save(JNIEnv*, jobject, jlong canvasHandle, jint flagsHandle) {
-    SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
+    SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
     return static_cast<jint>(get_canvas(canvasHandle)->save(flags));
 }
 
 static jint saveLayer(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t,
                       jfloat r, jfloat b, jlong paintHandle, jint flagsHandle) {
     Paint* paint  = reinterpret_cast<Paint*>(paintHandle);
-    SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
+    SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
     return static_cast<jint>(get_canvas(canvasHandle)->saveLayer(l, t, r, b, paint, flags));
 }
 
 static jint saveLayerAlpha(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, jfloat t,
                            jfloat r, jfloat b, jint alpha, jint flagsHandle) {
-    SkCanvas::SaveFlags flags = static_cast<SkCanvas::SaveFlags>(flagsHandle);
+    SaveFlags::Flags flags = static_cast<SaveFlags::Flags>(flagsHandle);
     return static_cast<jint>(get_canvas(canvasHandle)->saveLayerAlpha(l, t, r, b, alpha, flags));
 }
 
@@ -351,7 +351,7 @@
     if (CC_LIKELY(dstDensity == srcDensity || dstDensity == 0 || srcDensity == 0)) {
         canvas->drawNinePatch(skiaBitmap, *chunk, left, top, right, bottom, paint);
     } else {
-        canvas->save(SkCanvas::kMatrixClip_SaveFlag);
+        canvas->save(SaveFlags::MatrixClip);
 
         SkScalar scale = dstDensity / (float)srcDensity;
         canvas->translate(left, top);
@@ -390,7 +390,7 @@
             canvas->drawBitmap(bitmap, left, top, paint);
         }
     } else {
-        canvas->save(SkCanvas::kMatrixClip_SaveFlag);
+        canvas->save(SaveFlags::MatrixClip);
         SkScalar scale = canvasDensity / (float)bitmapDensity;
         canvas->translate(left, top);
         canvas->scale(scale, scale);
diff --git a/core/jni/android_os_HardwarePropertiesManager.cpp b/core/jni/android_os_HardwarePropertiesManager.cpp
new file mode 100644
index 0000000..dc1ba48
--- /dev/null
+++ b/core/jni/android_os_HardwarePropertiesManager.cpp
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "HardwarePropertiesManager-JNI"
+
+#include "JNIHelp.h"
+#include "jni.h"
+
+#include <stdlib.h>
+
+#include <hardware/hardware_properties.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <hardware_properties/HardwarePropertiesManager.h>
+
+#include "core_jni_helpers.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+static struct {
+    jclass clazz;
+    jmethodID initMethod;
+} gCpuUsageInfoClassInfo;
+
+static struct hardware_properties_module* gHardwarePropertiesModule;
+
+// ----------------------------------------------------------------------------
+
+static void nativeInit(JNIEnv* env, jobject obj) {
+    status_t err = hw_get_module(HARDWARE_PROPERTIES_HARDWARE_MODULE_ID,
+            (hw_module_t const**)&gHardwarePropertiesModule);
+    if (err) {
+        ALOGE("Couldn't load %s module (%s)", HARDWARE_PROPERTIES_HARDWARE_MODULE_ID,
+              strerror(-err));
+    }
+}
+
+static jfloatArray nativeGetFanSpeeds(JNIEnv *env, jclass /* clazz */) {
+    if (gHardwarePropertiesModule && gHardwarePropertiesModule->getFanSpeeds) {
+        float *speeds = nullptr;
+        ssize_t size = gHardwarePropertiesModule->getFanSpeeds(gHardwarePropertiesModule, &speeds);
+
+        if (speeds && size > 0) {
+            jfloatArray fanSpeeds = env->NewFloatArray(size);
+            env->SetFloatArrayRegion(fanSpeeds, 0, size, speeds);
+            free(speeds);
+            return fanSpeeds;
+        }
+
+        if (size < 0) {
+            ALOGE("Cloudn't get fan speeds because of HAL error");
+        }
+    }
+    return env->NewFloatArray(0);
+}
+
+static jfloatArray nativeGetDeviceTemperatures(JNIEnv *env, jclass /* clazz */, int type) {
+    if (gHardwarePropertiesModule) {
+        ssize_t size = 0;
+        float *temps = nullptr;
+        switch (type) {
+        case DEVICE_TEMPERATURE_CPU:
+            if (gHardwarePropertiesModule->getCpuTemperatures) {
+                size = gHardwarePropertiesModule->getCpuTemperatures(gHardwarePropertiesModule,
+                                                                     &temps);
+            }
+            break;
+        case DEVICE_TEMPERATURE_GPU:
+            if (gHardwarePropertiesModule->getGpuTemperatures) {
+                size = gHardwarePropertiesModule->getGpuTemperatures(gHardwarePropertiesModule,
+                                                                    &temps);
+            }
+            break;
+        case DEVICE_TEMPERATURE_BATTERY:
+            if (gHardwarePropertiesModule->getBatteryTemperatures) {
+                size = gHardwarePropertiesModule->getBatteryTemperatures(gHardwarePropertiesModule,
+                                                                        &temps);
+            }
+            break;
+        }
+        if (temps && size > 0) {
+            jfloatArray deviceTemps = env->NewFloatArray(size);
+            env->SetFloatArrayRegion(deviceTemps, 0, size, temps);
+            free(temps);
+            return deviceTemps;
+        }
+        if (size < 0) {
+            ALOGE("Couldn't get device temperatures type=%d because of HAL error", type);
+        }
+    }
+    return env->NewFloatArray(0);
+}
+
+static jobjectArray nativeGetCpuUsages(JNIEnv *env, jclass /* clazz */) {
+    if (gHardwarePropertiesModule && gHardwarePropertiesModule->getCpuUsages
+        && gCpuUsageInfoClassInfo.initMethod) {
+        int64_t *active_times = nullptr;
+        int64_t *total_times = nullptr;
+        ssize_t size = gHardwarePropertiesModule->getCpuUsages(gHardwarePropertiesModule,
+                                                               &active_times, &total_times);
+        if (active_times && total_times && size > 0) {
+            jobjectArray cpuUsages = env->NewObjectArray(size, gCpuUsageInfoClassInfo.clazz,
+                                                         nullptr);
+            for (ssize_t i = 0; i < size; ++i) {
+                jobject cpuUsage = env->NewObject(gCpuUsageInfoClassInfo.clazz,
+                                                  gCpuUsageInfoClassInfo.initMethod,
+                                                  active_times[i], total_times[i]);
+                env->SetObjectArrayElement(cpuUsages, i, cpuUsage);
+            }
+            free(active_times);
+            free(total_times);
+            return cpuUsages;
+        }
+
+        if (size < 0) {
+            ALOGE("Couldn't get CPU usages because of HAL error");
+        }
+    }
+    return env->NewObjectArray(0, gCpuUsageInfoClassInfo.clazz, nullptr);
+}
+
+// ----------------------------------------------------------------------------
+
+static const JNINativeMethod gHardwarePropertiesManagerMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeInit", "()V",
+            (void*) nativeInit },
+    { "nativeGetFanSpeeds", "()[F",
+            (void*) nativeGetFanSpeeds },
+    { "nativeGetDeviceTemperatures", "(I)[F",
+            (void*) nativeGetDeviceTemperatures },
+    { "nativeGetCpuUsages", "()[Landroid/os/CpuUsageInfo;",
+            (void*) nativeGetCpuUsages }
+};
+
+int register_android_os_HardwarePropertiesManager(JNIEnv* env) {
+    gHardwarePropertiesModule = nullptr;
+    int res = jniRegisterNativeMethods(env, "android/os/HardwarePropertiesManager",
+                                       gHardwarePropertiesManagerMethods,
+                                       NELEM(gHardwarePropertiesManagerMethods));
+    jclass clazz = env->FindClass("android/os/CpuUsageInfo");
+    gCpuUsageInfoClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
+    gCpuUsageInfoClassInfo.initMethod = GetMethodIDOrDie(env, gCpuUsageInfoClassInfo.clazz,
+                                                         "<init>", "(JJ)V");
+    return res;
+}
+
+} /* namespace android */
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 5aa6a73..edced56 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -28,14 +28,18 @@
 #include <EGL/eglext.h>
 #include <EGL/egl_cache.h>
 
+#include <utils/Looper.h>
+#include <utils/RefBase.h>
 #include <utils/StrongPointer.h>
 #include <android_runtime/android_view_Surface.h>
 #include <system/window.h>
 
 #include "android_view_GraphicBuffer.h"
+#include "android_os_MessageQueue.h"
 
 #include <Animator.h>
 #include <AnimationContext.h>
+#include <FrameInfo.h>
 #include <IContextFactory.h>
 #include <JankTracker.h>
 #include <RenderNode.h>
@@ -50,6 +54,12 @@
 using namespace android::uirenderer;
 using namespace android::uirenderer::renderthread;
 
+struct {
+    jfieldID buffer;
+    jfieldID messageQueue;
+    jmethodID notifyData;
+} gFrameStatsObserverClassInfo;
+
 static JNIEnv* getenv(JavaVM* vm) {
     JNIEnv* env;
     if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
@@ -207,6 +217,99 @@
     RootRenderNode* mRootNode;
 };
 
+class ObserverProxy;
+
+class NotifyHandler : public MessageHandler {
+public:
+    NotifyHandler(JavaVM* vm) : mVm(vm) {}
+
+    void setObserver(ObserverProxy* observer) {
+        mObserver = observer;
+    }
+
+    void setBuffer(BufferPool::Buffer* buffer) {
+        mBuffer = buffer;
+    }
+
+    virtual void handleMessage(const Message& message);
+
+private:
+    JavaVM* mVm;
+
+    sp<ObserverProxy> mObserver;
+    BufferPool::Buffer* mBuffer;
+};
+
+class ObserverProxy : public FrameStatsObserver {
+public:
+    ObserverProxy(JavaVM *vm, jobject fso) : 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,
+                "unable to create frame stats observer reference");
+
+        jobject messageQueueLocal =
+                env->GetObjectField(fso, gFrameStatsObserverClassInfo.messageQueue);
+        mMessageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueLocal);
+        LOG_ALWAYS_FATAL_IF(mMessageQueue == nullptr, "message queue not available");
+
+        mMessageHandler = new NotifyHandler(mVm);
+        LOG_ALWAYS_FATAL_IF(mMessageHandler == nullptr,
+                "OOM: unable to allocate NotifyHandler");
+    }
+
+    ~ObserverProxy() {
+        JNIEnv* env = getenv(mVm);
+        env->DeleteWeakGlobalRef(mFsoWeak);
+    }
+
+    jweak getJavaObjectRef() {
+        return mFsoWeak;
+    }
+
+    virtual void notify(BufferPool::Buffer* buffer) {
+        buffer->incRef();
+        mMessageHandler->setBuffer(buffer);
+        mMessageHandler->setObserver(this);
+        mMessageQueue->getLooper()->sendMessage(mMessageHandler, mMessage);
+    }
+
+private:
+    static const int kBufferSize = static_cast<int>(FrameInfoIndex::NumIndexes);
+
+    JavaVM* mVm;
+    jweak mFsoWeak;
+
+    sp<MessageQueue> mMessageQueue;
+    sp<NotifyHandler> mMessageHandler;
+    Message mMessage;
+};
+
+void NotifyHandler::handleMessage(const Message& message) {
+    JNIEnv* env = getenv(mVm);
+
+    jobject target = env->NewLocalRef(mObserver->getJavaObjectRef());
+
+    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);
+        }
+    }
+
+    mBuffer->release();
+    mObserver.clear();
+}
+
 static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz,
         jlong proxyPtr, jobject graphicBuffer, jlongArray atlasMapArray) {
     sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer);
@@ -468,6 +571,42 @@
 }
 
 // ----------------------------------------------------------------------------
+// FrameStatsObserver
+// ----------------------------------------------------------------------------
+
+static jlong android_view_ThreadedRenderer_addFrameStatsObserver(JNIEnv* env,
+        jclass clazz, jlong proxyPtr, jobject fso) {
+    JavaVM* vm = nullptr;
+    if (env->GetJavaVM(&vm) != JNI_OK) {
+        LOG_ALWAYS_FATAL("Unable to get Java VM");
+        return 0;
+    }
+
+    renderthread::RenderProxy* renderProxy =
+            reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
+
+    FrameStatsObserver* observer = new ObserverProxy(vm, fso);
+    renderProxy->addFrameStatsObserver(observer);
+    return reinterpret_cast<jlong>(observer);
+}
+
+static void android_view_ThreadedRenderer_removeFrameStatsObserver(JNIEnv* env, jclass clazz,
+        jlong proxyPtr, jlong observerPtr) {
+    FrameStatsObserver* observer = reinterpret_cast<FrameStatsObserver*>(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();
+}
+
+// ----------------------------------------------------------------------------
 // Shaders
 // ----------------------------------------------------------------------------
 
@@ -523,9 +662,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",
+            "(JJ)V",
+            (void*)android_view_ThreadedRenderer_removeFrameStatsObserver },
+    { "nGetDroppedFrameReportCount",
+            "(J)J",
+            (void*)android_view_ThreadedRenderer_getDroppedFrameReportCount },
 };
 
 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");
+
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a82bfbe..5a2f601 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -339,7 +339,6 @@
     <protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" />
 
     <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED" />
-    <protected-broadcast android:name="android.intent.action.AVAILABILITY_CHANGED" />
 
     <!-- Added in N -->
     <protected-broadcast android:name="android.intent.action.ANR" />
@@ -384,6 +383,7 @@
     <protected-broadcast android:name="android.security.STORAGE_CHANGED" />
     <protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_REGISTERED" />
     <protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_UNREGISTERED" />
+    <protected-broadcast android:name="android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" />
     <protected-broadcast android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" />
 
     <protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" />
@@ -1208,7 +1208,8 @@
     <eat-comment />
 
     <!-- Allows access to the list of accounts in the Accounts Service.
-        <p>Protection level: normal
+         <p>Protection level: dangerous
+         @deprecated Not operative for apps apps with targetSdkVersion >= 24.
     -->
     <permission android:name="android.permission.GET_ACCOUNTS"
         android:permissionGroup="android.permission-group.CONTACTS"
@@ -2859,6 +2860,12 @@
     <permission android:name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- Must be required by system/priv apps when accessing the sound trigger
+         APIs given by {@link SoundTriggerManager}.
+         @hide <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.MANAGE_SOUND_TRIGGER"
+        android:protectionLevel="signature|privileged" />
+
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
@@ -3020,6 +3027,12 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="com.android.internal.app.UnlaunchableAppActivity"
+                android:theme="@style/Theme.Material.DayNight.Dialog.Alert"
+                android:excludeFromRecents="true"
+                android:process=":ui">
+        </activity>
+
         <receiver android:name="com.android.server.BootReceiver"
                 android:systemUserOnly="true">
             <intent-filter android:priority="1000">
diff --git a/core/res/res/drawable-xhdpi/pointer_alias_large.png b/core/res/res/drawable-xhdpi/pointer_alias_large.png
new file mode 100644
index 0000000..813cd2a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_alias_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_all_scroll_large.png b/core/res/res/drawable-xhdpi/pointer_all_scroll_large.png
new file mode 100644
index 0000000..f101077
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_all_scroll_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_arrow_large.png b/core/res/res/drawable-xhdpi/pointer_arrow_large.png
new file mode 100644
index 0000000..0f9165b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_cell_large.png b/core/res/res/drawable-xhdpi/pointer_cell_large.png
new file mode 100644
index 0000000..b41f855
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_cell_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_context_menu_large.png b/core/res/res/drawable-xhdpi/pointer_context_menu_large.png
new file mode 100644
index 0000000..6264e0b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_context_menu_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_copy_large.png b/core/res/res/drawable-xhdpi/pointer_copy_large.png
new file mode 100644
index 0000000..5e7f375
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_copy_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_crosshair_large.png b/core/res/res/drawable-xhdpi/pointer_crosshair_large.png
new file mode 100644
index 0000000..d5f4502
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_crosshair_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_grab_large.png b/core/res/res/drawable-xhdpi/pointer_grab_large.png
new file mode 100644
index 0000000..bf99b79
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_grab_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_grabbing_large.png b/core/res/res/drawable-xhdpi/pointer_grabbing_large.png
new file mode 100644
index 0000000..e576bcd
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_grabbing_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_hand_large.png b/core/res/res/drawable-xhdpi/pointer_hand_large.png
new file mode 100644
index 0000000..76fa09b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_hand_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_help_large.png b/core/res/res/drawable-xhdpi/pointer_help_large.png
new file mode 100644
index 0000000..a45f039
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_help_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow_large.png b/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow_large.png
new file mode 100644
index 0000000..9b2a312
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_horizontal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_nodrop_large.png b/core/res/res/drawable-xhdpi/pointer_nodrop_large.png
new file mode 100644
index 0000000..f140532
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_nodrop_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_text_large.png b/core/res/res/drawable-xhdpi/pointer_text_large.png
new file mode 100644
index 0000000..56be154
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_text_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow_large.png b/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow_large.png
new file mode 100644
index 0000000..9e6a8b6
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_top_left_diagonal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow_large.png b/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow_large.png
new file mode 100644
index 0000000..2631094
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_top_right_diagonal_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow_large.png b/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow_large.png
new file mode 100644
index 0000000..5ec65e0
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_vertical_double_arrow_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_vertical_text_large.png b/core/res/res/drawable-xhdpi/pointer_vertical_text_large.png
new file mode 100644
index 0000000..26c46de
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_vertical_text_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_zoom_in_large.png b/core/res/res/drawable-xhdpi/pointer_zoom_in_large.png
new file mode 100644
index 0000000..c2b845f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_zoom_in_large.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_zoom_out_large.png b/core/res/res/drawable-xhdpi/pointer_zoom_out_large.png
new file mode 100644
index 0000000..148ed25
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/pointer_zoom_out_large.png
Binary files differ
diff --git a/core/res/res/layout/app_error_dialog.xml b/core/res/res/layout/app_error_dialog.xml
new file mode 100644
index 0000000..aaa2dbc
--- /dev/null
+++ b/core/res/res/layout/app_error_dialog.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:paddingTop="@dimen/dialog_list_padding_vertical_material"
+        android:paddingBottom="@dimen/dialog_list_padding_vertical_material"
+>
+
+
+    <TextView
+            android:id="@+id/aerr_restart"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/aerr_restart"
+            style="@style/aerr_list_item"
+    />
+
+    <TextView
+            android:id="@+id/aerr_reset"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/aerr_reset"
+            style="@style/aerr_list_item"
+    />
+
+    <TextView
+            android:id="@+id/aerr_report"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/aerr_report"
+            style="@style/aerr_list_item"
+    />
+
+    <TextView
+            android:id="@+id/aerr_close"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/aerr_close"
+            style="@style/aerr_list_item"
+    />
+
+    <TextView
+            android:id="@+id/aerr_mute"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/aerr_mute"
+            style="@style/aerr_list_item"
+    />
+
+
+</LinearLayout>
diff --git a/core/res/res/layout/app_error_dialog_dont_show_again.xml b/core/res/res/layout/app_error_dialog_dont_show_again.xml
deleted file mode 100644
index ba79ecd..0000000
--- a/core/res/res/layout/app_error_dialog_dont_show_again.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:paddingStart="14dp"
-        android:paddingEnd="10dp"
-        android:gravity="center_vertical"
-        >
-    <CheckBox
-            android:id="@+id/checkbox"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            />
-    <TextView
-            android:id="@+id/text"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dp"
-            android:layout_marginBottom="8dp"
-            />
-
-</LinearLayout>
diff --git a/core/res/res/layout/unlaunchable_app_activity.xml b/core/res/res/layout/unlaunchable_app_activity.xml
new file mode 100644
index 0000000..429d5ed
--- /dev/null
+++ b/core/res/res/layout/unlaunchable_app_activity.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="@dimen/dialog_padding"
+        android:orientation="vertical">
+        <TextView android:id="@+id/unlaunchable_app_title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingStart="@dimen/dialog_padding"
+                android:paddingBottom="@dimen/dialog_padding"
+                android:textAppearance="@android:style/TextAppearance.Material.Title" />
+
+        <TextView android:id="@+id/unlaunchable_app_message"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingStart="@dimen/dialog_padding"
+                android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+                android:textColor="?android:attr/textColorSecondary" />
+</LinearLayout>
+
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 463ee0a..eae2c44 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Foutverslag"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Neem foutverslag"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Dit sal inligting oor die huidige toestand van jou toestel insamel om as \'n e-posboodskap te stuur. Dit sal \'n tydjie neem vandat die foutverslag begin is totdat dit reg is om gestuur te word; wees asseblief geduldig."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiewe verslag"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Gebruik dit in die meeste omstandighede. Maak dit vir jou moontlik om die vordering van die verslag na te spoor en meer besonderhede oor die probleem in te voer. Dit sal dalk sommige afdelings weglaat wat minder gebruik word en waarvoor verslagdoening lank duur."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Volle verslag"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Neem skermkiekie vir foutverslag oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes.</item>
+      <item quantity="one">Neem skermkiekie vir foutverslag oor <xliff:g id="NUMBER_0">%d</xliff:g> sekonde.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Stilmodus"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Klank is AF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Klank is AAN"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Raak om te kanselleer"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Verander sleutelbord"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Kies sleutelborde"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Wys invoermetode"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardeware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Hou dit op die skerm terwyl fisieke sleutelbord aktief is"</string>
+    <string name="hardware" msgid="194658061510127999">"Wys virtuele sleutelbord"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Kies sleutelborduitleg"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Raak om \'n sleutelborduitleg te kies."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeer tans om \'n nuwe gebruiker by te voeg, maar die gebruikerlimiet is bereik."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeer tans om \'n nuwe gebruiker by te voeg, maar die rekening "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" bestaan reeds op hierdie toestel. Gaan in elk geval voort?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeer tans om \'n nuwe gebruiker vir die rekening "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" by te voeg. Gaan voort?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Taalvoorkeur"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Streekvoorkeur"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Voer taalnaam in"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Voorgestel"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Alle tale"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Soek"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index a4b502c..85ef3c5 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"የሳንካ ሪፖርት"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"የሳንካ ሪፖርት ውሰድ"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ይሄ እንደ የኢሜይል መልዕክት አድርጎ የሚልከውን ስለመሣሪያዎ የአሁኑ ሁኔታ መረጃ ይሰበስባል። የሳንካ ሪፖርቱን ከመጀመር ጀምሮ እስኪላክ ድረስ ትንሽ ጊዜ ይወስዳል፤ እባክዎ ይታገሱ።"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"መስተጋብራዊ ሪፖርት"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"በአብዛኛዎቹ ሁኔታዎች ይህን ይጠቀሙ። የሪፖርቱን ሂደት እንዲከታተሉ እና ስለችግሩ ተጨማሪ ዝርዝሮችን እንዲያስገቡ ያስችልዎታል። ሪፖርት ለማድረግ በጣም ረዥም ጊዜ የሚወስዱ አንዳንድ ብዙም ጥቅም ላይ የማይውሉ ክፍሎችን ሊያልፋቸው ይችላል።"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"ሙሉ ሪፖርት"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">በ<xliff:g id="NUMBER_1">%d</xliff:g> ሰከንዶች ውስጥ ለሳንካ ሪፖርት ቅጽበታዊ ገጽ ዕይታን በማንሳት ላይ።</item>
+      <item quantity="other">በ<xliff:g id="NUMBER_1">%d</xliff:g> ሰከንዶች ውስጥ ለሳንካ ሪፖርት ቅጽበታዊ ገጽ ዕይታን በማንሳት ላይ።</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"የፀጥታ ሁነታ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ድምፅ ጠፍቷል"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ድምፅ በርቷል"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ለመሰረዝ ይንኩ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ቁልፍ ሰሌዳ ይቀይሩ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ቁልፍ ሰሌዳዎችን ምረጥ"</string>
-    <string name="show_ime" msgid="9157568568695230830">"የግቤት ስልት አሳይ"</string>
-    <string name="hardware" msgid="7517821086888990278">"ሃርድዌር"</string>
+    <string name="show_ime" msgid="2506087537466597099">"አካላዊ የቁልፍ ሰሌዳ ገቢር ሆኖ ሳለ በማያ ገጽ ላይ አቆየው"</string>
+    <string name="hardware" msgid="194658061510127999">"ምናባዊ የቁልፍ ሰሌዳን አሳይ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"የቁልፍ ሰሌዳ አቀማመጥ ምረጥ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"የቁልፍ ሰሌዳ አቀማመጥ ለመምረጥ ንካ።"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" አዲስ ተጠቃሚ ለማከል እየሞከረ ነው፣ ሆኖም ግን የተጠቃሚ ብዛት ገደብ ላይ ተደርሷል።"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" አዲስ ተጠቃሚ ለማከል እየሞከረ ነው፣ ነገር ግን መለያ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" አስቀድሞ በዚህ መሣሪያ ላይ አለ። የሆነው ሆኖ ይቀጥል?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ለ"<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" መለያ አዲስ ተጠቃሚ ለማከል እየሞከረ ነው። ይቀጥል?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"የቋንቋ ምርጫ"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"የክልል ምርጫ"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"የቋንቋ ስም ይተይቡ"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"የተጠቆሙ"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ሁሉም ቋንቋዎች"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"ፈልግ"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index ae22ede..bcab357 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -215,15 +215,19 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"تقرير الأخطاء"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"إعداد تقرير بالأخطاء"</string>
     <string name="bugreport_message" msgid="398447048750350456">"سيجمع هذا معلومات حول حالة جهازك الحالي لإرسالها كرسالة إلكترونية، ولكنه سيستغرق وقتًا قليلاً من بدء عرض تقرير بالأخطاء. وحتى يكون جاهزًا للإرسال، الرجاء الانتظار."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"تقرير تفاعلي"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"يمكنك استخدام هذا الخيار في معظم الأحيان، حيث يتيح لك إمكانية تتبع مستوى تقدم التقرير والحصول على مزيد من المعلومات حول المشكلة. وقد يتم إسقاط بعض الأقسام الأقل استخدامًا والتي تستغرق وقتًا طويلاً أثناء إعداد التقرير."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"تقرير كامل"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="zero">سيتم التقاط لقطة شاشة لتقرير الخطأ خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية.</item>
+      <item quantity="two">سيتم التقاط لقطة شاشة لتقرير الخطأ خلال ثانيتين (<xliff:g id="NUMBER_1">%d</xliff:g>).</item>
+      <item quantity="few">سيتم التقاط لقطة شاشة لتقرير الخطأ خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثوانٍ.</item>
+      <item quantity="many">سيتم التقاط لقطة شاشة لتقرير الخطأ خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية.</item>
+      <item quantity="other">سيتم التقاط لقطة شاشة لتقرير الخطأ خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية.</item>
+      <item quantity="one">سيتم التقاط لقطة شاشة لتقرير الخطأ خلال <xliff:g id="NUMBER_0">%d</xliff:g> ثانية.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"وضع صامت"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"الصوت متوقف"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"الصوت قيد التشغيل"</string>
@@ -1077,8 +1081,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"المس للإلغاء"</string>
     <string name="select_input_method" msgid="8547250819326693584">"تغيير لوحة المفاتيح"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"اختيار لوحات المفاتيح"</string>
-    <string name="show_ime" msgid="9157568568695230830">"إظهار طريقة الإدخال"</string>
-    <string name="hardware" msgid="7517821086888990278">"أجهزة"</string>
+    <string name="show_ime" msgid="2506087537466597099">"استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية"</string>
+    <string name="hardware" msgid="194658061510127999">"إظهار لوحة المفاتيح الظاهرية"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"تحديد تخطيط لوحة مفاتيح"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"المس لتحديد تخطيط لوحة مفاتيح."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
@@ -1603,4 +1607,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"هناك محاولة من "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" لإضافة مستخدم جديد إلا أنه قد تم الوصول إلى الحد الأقصى للمستخدمين."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"هناك محاولة من "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" لإضافة مستخدم جديد إلا أن الحساب "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" موجود مسبقًا على هذا الجهاز، فهل تريد المتابعة على أي حال؟"</string>
     <string name="user_creation_adding" msgid="3206420861363021392">"هناك محاولة من "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" لإضافة مستخدم جديد إلى الحساب "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"، فهل تريد المتابعة؟"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"تفضيل اللغة"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"تفضيل المنطقة"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"اكتب اسم اللغة"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"المقترحة"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"جميع اللغات"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"البحث"</string>
 </resources>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index b38d303..05ce1c0 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Baq hesabatı"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Baqı xəbər verin"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Bu, sizin hazırkı cihaz durumu haqqında məlumat toplayacaq ki, elektron məktub şəklində göndərsin. Baq raportuna başlamaq üçün bir az vaxt lazım ola bilər, bir az səbr edin."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"İnteraktiv hesabat"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Bir çox hallarda bundan istifadə edin. Bu hesabatın gedişatını izləməyə və problem haqqında daha ətraflı məlumat daxil etməyə imkan verir. Bu, çox vaxt tələb edən bəzi az istifadə olunan bölmələri ixtisar edə bilər."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Tam hesabat"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Baq hesabatı üçün <xliff:g id="NUMBER_1">%d</xliff:g> saniyədə sktinşot çəkilir.</item>
+      <item quantity="one">Baq hesabatı üçün <xliff:g id="NUMBER_0">%d</xliff:g> saniyədə skrinşot çəkilir.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Səssiz rejim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Səs qapalıdır"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Səs Aktivdir"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Ləğv etmək üçün toxunun"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviaturanı dəyişin"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturaları seçin"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Daxiletmə metodunu göstərin"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Fiziki klaviatura aktiv olduğu halda ekranda saxlayın"</string>
+    <string name="hardware" msgid="194658061510127999">"Virtual klaviaturanı göstərin"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Klaviatura sxemi seçin"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Klaviatura tərtibatı seçmək üçün toxunun."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCÇDEƏFGĞHXIİJKQLMNOÖPRSŞTUÜVYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yeni istifadəçi əlavə etməyə çalışır, lakin istifadəçi limitinə çatılıb."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yeni istifadəçi əlavə etməyə çalışır, lakin "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hesabı bu cihazda artıq mövcuddur. Hər bir halda davam edilsin?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hesabı üçün yeni istifadəçi əlavə etməyə çalışır. Davam edilsin?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Dil seçimi"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Region seçimi"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Dil adını daxil edin"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Təklif edilmiş"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Bütün dillər"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Axtarın"</string>
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index e69dd9a..7e5106a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -212,15 +212,16 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izveštaj o grešci"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Napravi izveštaj o grešci"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ovim će se prikupiti informacije o trenutnom stanju uređaja kako bi bile poslate u poruci e-pošte. Od započinjanja izveštaja o grešci do trenutka za njegovo slanje proći će neko vreme; budite strpljivi."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv. izveštaj"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Koristite ovo u većini slučajeva. To vam omogućava da pratite napredak izveštaja i da unosite dodatne detalje o problemu. Verovatno će izostaviti neke manje korišćene odeljke za koje pravljenje izveštaja dugo traje."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Kompletan izveštaj"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Napravićemo snimak ekrana radi izveštaja o grešci za <xliff:g id="NUMBER_1">%d</xliff:g> sekundu.</item>
+      <item quantity="few">Napravićemo snimak ekrana radi izveštaja o grešci za <xliff:g id="NUMBER_1">%d</xliff:g> sekunde.</item>
+      <item quantity="other">Napravićemo snimak ekrana radi izveštaja o grešci za <xliff:g id="NUMBER_1">%d</xliff:g> sekundi.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Nečujni režim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je ISKLJUČEN"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je UKLJUČEN"</string>
@@ -1056,8 +1057,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Dodirnite da biste otkazali"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promenite tastaturu"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Izaberite tastature"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Prikazivanje metoda unosa"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardver"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Zadrži ga na ekranu dok je fizička tastatura aktivna"</string>
+    <string name="hardware" msgid="194658061510127999">"Prikaži virtuelnu tastaturu"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Izbor rasporeda tastature"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dodirnite da biste izabrali raspored tastature."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1549,4 +1550,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava da doda novog korisnika, ali je ograničenje za broj korisnika dostignuto."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava da doda novog korisnika, ali nalog "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" već postoji na ovom uređaju. Želite li ipak da nastavite?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava da doda novog korisnika za nalog "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Želite li da nastavite?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Podešavanje jezika"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Podešavanje regiona"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Unesite naziv jezika"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Predloženi"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Svi jezici"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Pretraži"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d15a738..297d50b 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Сигнал за програмна грешка"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Сигнал за програмна грешка"</string>
     <string name="bugreport_message" msgid="398447048750350456">"По този начин ще се събере информация за текущото състояние на устройството ви, която да се изпрати като имейл съобщение. След стартирането на процеса ще мине известно време, докато сигналът за програмна грешка бъде готов за подаване. Моля, имайте търпение."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивен сигнал"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Използвайте тази опция в повечето случаи. Тя ви позволява да проследявате напредъка на сигнала и да въвеждате още данни за проблема. Възможно е някои по-малко използвани секции, за които подаването на сигнал отнема дълго време, да бъдат пропуснати."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Пълен сигнал"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Екранната снимка за сигнала за програмна грешка ще бъде направена след <xliff:g id="NUMBER_1">%d</xliff:g> секунди.</item>
+      <item quantity="one">Екранната снимка за сигнала за програмна грешка ще бъде направена след <xliff:g id="NUMBER_0">%d</xliff:g> секунда.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Тих режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звукът е ИЗКЛЮЧЕН"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звукът е ВКЛЮЧЕН"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Докоснете, за да анулирате"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Промяна на клавиатурата"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Избиране на клавиатури"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Метод на въвежд.: Показв."</string>
-    <string name="hardware" msgid="7517821086888990278">"Хардуер"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Показване на екрана, докато физическата клавиатура е активна"</string>
+    <string name="hardware" msgid="194658061510127999">"Показване на вирт. клавиатура"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Избиране на клавиатурна подредба"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Докоснете, за да изберете клавиатурна подредба."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" опитва да добави нов потребител, но ограничението за брой потребители е достигнато."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" опитва да добави нов потребител, но профилът "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" вече съществува на устройството. Да се продължи ли въпреки това?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" опитва да добави нов потребител за профила "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Да се продължи ли?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Езиково предпочитание"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Предпочитание за региона"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Въведете име на език"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Предложени"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Всички езици"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Търсене"</string>
 </resources>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index bb267f3..b9a1cd8 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ত্রুটির প্রতিবেদন"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ত্রুটির প্রতিবেদন করুন"</string>
     <string name="bugreport_message" msgid="398447048750350456">"এটি একটি ই-মেল বার্তা পাঠানোর জন্য আপনার ডিভাইসের বর্তমান অবস্থা সম্পর্কে তথ্য সংগ্রহ করবে৷ ত্রুটির প্রতিবেদন শুরুর সময় থেকে এটি পাঠানোর জন্য প্রস্তুত হতে কিছুটা সময় নেবে; দয়া করে ধৈর্য রাখুন৷"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ইন্টারেক্টিভ প্রতিবেদন"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"বেশিভাগ পরিস্থিতিতে এটিকে ব্যবহার করুন৷ এটি আপনাকে প্রতিবেদনের কাজ কতটা হয়েছে তার উপর নজর রাখতে দেয় এবং সমস্যাটির সম্পর্কে আরো অনেক কিছু লিখতে দেয়৷ এটি হয়ত প্রতিবেদন করতে খুব বেশি সময় নেয় এমন কম-ব্যবহৃত বিভাগগুলি সরিয়ে দিতে পারে৷"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"সম্পূর্ণ প্রতিবেদন"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one"><xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে ত্রুটির প্রতিবেদনের জন্য স্ক্রীনশট নেওয়া হচ্ছে৷</item>
+      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> সেকেন্ডের মধ্যে ত্রুটির প্রতিবেদনের জন্য স্ক্রীনশট নেওয়া হচ্ছে৷</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"নীরব মোড"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"শব্দ বন্ধ করা আছে"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"শব্দ চালু করা আছে"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"বাতিল করতে স্পর্শ করুন"</string>
     <string name="select_input_method" msgid="8547250819326693584">"কীবোর্ড পরিবর্তন করুন"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"কীবোর্ড চয়ন করুন"</string>
-    <string name="show_ime" msgid="9157568568695230830">"ইনপুট পদ্ধতি দেখান"</string>
-    <string name="hardware" msgid="7517821086888990278">"হার্ডওয়্যার"</string>
+    <string name="show_ime" msgid="2506087537466597099">"ফিজিক্যাল কীবোর্ড সক্রিয় থাকার সময় এটিকে স্ক্রীনে রাখুন"</string>
+    <string name="hardware" msgid="194658061510127999">"ভার্চুয়াল কীবোর্ড দেখান"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"কীবোর্ডের লেআউট নির্বাচন করুন"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"একটি কীবোর্ডের লেআউট নির্বাচন করতে স্পর্শ করুন৷"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" একজন নতুন ব্যবহারকারী যোগ করার চেষ্টা করছে, তবে ব্যবহারকারীর সীমা অতিক্রান্ত হয়েছে।"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" একজন নতুন ব্যবহারকারীকে যোগ করার চেষ্টা করছে, তবে "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" অ্যাকাউন্ট আগে থেকেই এই ডিভাইসটিতে বিদ্যমান আছে। তবুও এগোতে চান?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" অ্যাকাউন্টের জন্য একজন নতুন ব্যবহারকারীকে যোগ করার চেষ্টা করছে। এগোতে চান?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"পছন্দের ভাষা"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"পছন্দের অঞ্চল"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"ভাষার নাম লিখুন"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"প্রস্তাবিত"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"সকল ভাষা"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"অনুসন্ধান করুন"</string>
 </resources>
diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml
new file mode 100644
index 0000000..6a5ef12
--- /dev/null
+++ b/core/res/res/values-bs-rBA/strings.xml
@@ -0,0 +1,2858 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- 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-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 />
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
+    <skip />
+    <!-- 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 />
+    <!-- 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-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-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="aerr_title" msgid="1905800560317137752"></string>
+    <!-- no translation found for aerr_application (932628488013092776) -->
+    <skip />
+    <!-- no translation found for aerr_process (4507058997035697579) -->
+    <skip />
+    <!-- no translation found for aerr_process_silence (4226685530196000222) -->
+    <skip />
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <!-- no translation found for anr_activity_application (1904477189057199066) -->
+    <skip />
+    <!-- no translation found for anr_activity_process (5776209883299089767) -->
+    <skip />
+    <!-- no translation found for anr_application_process (8941757607340481057) -->
+    <skip />
+    <!-- no translation found for anr_process (6513209874880517125) -->
+    <skip />
+    <!-- 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 />
+    <!-- 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 />
+    <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+    <skip />
+    <!-- no translation found for date_picker_dialog_title (5879450659453782278) -->
+    <skip />
+    <!-- no translation found for date_time_set (5777075614321087758) -->
+    <skip />
+    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <skip />
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <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 />
+    <!-- no translation found for dock_non_resizeble_text (9156251681042762723) -->
+    <skip />
+    <!-- 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 />
+    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
+    <skip />
+    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
+    <skip />
+    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
+    <skip />
+    <!-- no translation found for user_creation_adding (3206420861363021392) -->
+    <skip />
+    <!-- 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 />
+</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index ba52781..602532c 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe d\'error"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Crea informe d\'errors"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Es recopilarà informació sobre l\'estat actual del dispositiu i se t\'enviarà per correu electrònic. Passaran uns quants minuts des de l\'inici de l\'informe d\'errors fins al seu enviament, per la qual cosa et recomanem que tinguis paciència."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Informe interactiu"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Utilitza aquesta opció en la majoria de circumstàncies. Et permet fer un seguiment del progrés de l\'informe i introduir més dades sobre el problema. És possible que ometi seccions menys utilitzades que requereixen molt de temps i que no n\'informi."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Informe complet"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Es farà una captura de pantalla de l\'informe d\'errors d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons.</item>
+      <item quantity="one">Es farà una captura de pantalla de l\'informe d\'errors d\'aquí a <xliff:g id="NUMBER_0">%d</xliff:g> segon.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode silenciós"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"So desactivat"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"El so està activat"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toca per cancel·lar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Canvia el teclat"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Tria els teclats"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Mostra mètode d\'introducció"</string>
-    <string name="hardware" msgid="7517821086888990278">"Maquinari"</string>
+    <string name="show_ime" msgid="2506087537466597099">"El deixa a la pantalla mentre el teclat físic està actiu"</string>
+    <string name="hardware" msgid="194658061510127999">"Mostra el teclat virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona una disposició de teclat"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toca per seleccionar una disposició de teclat."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" està provant d\'afegir un usuari, però s\'ha assolit el límit d\'usuaris."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" està provant d\'afegir un usuari, però el compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ja existeix en aquest dispositiu. Vols continuar igualment?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" està provant d\'afegir un usuari per al compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vols continuar?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferència d\'idioma"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferència de regió"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Nom de l\'idioma"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Suggerits"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Tots els idiomes"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Cerca"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 1a73069..4c830f9 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -213,15 +213,17 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Hlášení chyb"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Vytvořit chybové hlášení"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Shromažďuje informace o aktuálním stavu zařízení. Tyto informace je následně možné poslat v e-mailové zprávě, chvíli však potrvá, než bude hlášení o chybě připraveno k odeslání. Buďte prosím trpěliví."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktivní přehled"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Tato možnost se používá ve většině případů. Umožňuje sledovat průběh přehledu a zadat další podrobnosti o problému. Mohou být vynechány některé méně používané sekce, jejichž kontrola trvá dlouho."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Úplný přehled"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="few">Snímek obrazovky pro zprávu o chybě bude pořízen za <xliff:g id="NUMBER_1">%d</xliff:g> sekundy.</item>
+      <item quantity="many">Snímek obrazovky pro zprávu o chybě bude pořízen za <xliff:g id="NUMBER_1">%d</xliff:g> sekundy.</item>
+      <item quantity="other">Snímek obrazovky pro zprávu o chybě bude pořízen za <xliff:g id="NUMBER_1">%d</xliff:g> sekund.</item>
+      <item quantity="one">Snímek obrazovky pro zprávu o chybě bude pořízen za <xliff:g id="NUMBER_0">%d</xliff:g> sekundu.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tichý režim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je VYPNUTÝ."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je zapnutý"</string>
@@ -1063,8 +1065,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Klepnutím zrušíte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Změna klávesnice"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vybrat klávesnici"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Zobrazit metodu zadávání"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Ponechat na obrazovce, když je aktivní fyzická klávesnice"</string>
+    <string name="hardware" msgid="194658061510127999">"Zobrazit virtuální klávesnici"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Výběr rozložení klávesnice"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotykem vyberte rozložení klávesnice."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
@@ -1567,4 +1569,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Aplikace "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" se pokouší přidat nového uživatele, avšak byl dosažen maximální počet uživatelů."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"Aplikace "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" se pokouší přidat nového uživatele, avšak účet "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" již v zařízení existuje. Chcete přesto pokračovat?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392">"Aplikace "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" se pro účet "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" pokouší přidat nového uživatele. Pokračovat?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferovaný jazyk"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferovaná oblast"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Zadejte název jazyka"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Navrhované"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Všechny jazyky"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Vyhledávání"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 791a379..164ae6b 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Fejlrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Lav fejlrapport"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Der indsamles oplysninger om din enheds aktuelle status, der efterfølgende sendes i en e-mail. Der går lidt tid, fra fejlrapporten påbegyndes, til den er klar til at blive sendt. Tak for tålmodigheden."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv rapport"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Brug dette workflow under de fleste omstændigheder. Det giver dig mulighed for at se status på rapporten og angive flere oplysninger om problemet. Nogle mindre brugte sektioner, der tager lang tid at rapportere, udelades muligvis."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Fuld rapport"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Der tages et skærmbillede til fejlrapporten om <xliff:g id="NUMBER_1">%d</xliff:g> sekund.</item>
+      <item quantity="other">Der tages et skærmbillede til fejlrapporten om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Lydløs"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Lyden er slået FRA"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Lyden er TIL"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tryk for at annullere"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Skift tastatur"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vælg tastaturer"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Vis indtastningsmetode"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Behold den på skærmen, mens det fysiske tastatur er aktivt"</string>
+    <string name="hardware" msgid="194658061510127999">"Vis virtuelt tastatur"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Vælg tastaturlayout"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Tryk for at vælge et tastaturlayout."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" forsøger at tilføje en ny bruger, men grænsen for antal brugere er nået."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" forsøger at tilføje en ny bruger, men kontoen "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" findes allerede på denne enhed. Vil du fortsætte?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" forsøger at føje en ny bruger til kontoen "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vil du fortsætte?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Sprogindstilling"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Områdeindstilling"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Angiv sprogets navn"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Foreslået"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Alle sprog"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Søg"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index a28d2b8..4f43c2a 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Fehlerbericht"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Fehlerbericht abrufen"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Bei diesem Fehlerbericht werden Daten zum aktuellen Status deines Geräts erfasst und als E-Mail versandt. Vom Start des Berichts bis zu seinem Versand kann es eine Weile dauern. Bitte habe etwas Geduld."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiver Bericht"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Diese Option kann in den meisten Fällen verwendet werden. Du kannst darüber den aktuellen Stand der Berichterstellung verfolgen und genauere Angaben zu dem Problem machen. Einige selten genutzte Bereiche, deren Berichterstellung längere Zeit in Anspruch nimmt, werden unter Umständen ausgelassen."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Vollständiger Bericht"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Screenshot für den Fehlerbericht wird in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden aufgenommen.</item>
+      <item quantity="one">Screenshot für den Fehlerbericht wird in <xliff:g id="NUMBER_0">%d</xliff:g> Sekunde aufgenommen.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Lautlos-Modus"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ton ist AUS."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ton ist AN."</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Zum Abbrechen tippen"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Tastatur ändern"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Tastatur auswählen"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Eingabemethode anzeigen"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Auf dem Display einblenden, wenn die physische Tastatur aktiv ist"</string>
+    <string name="hardware" msgid="194658061510127999">"Virtuelle Tastatur einblenden"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Tastaturlayout auswählen"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Zum Auswählen eines Tastaturlayouts berühren"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" versucht, einen neuen Nutzer hinzuzufügen. Die maximal zulässige Anzahl an Nutzern ist aber schon erreicht."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" versucht, einen neuen Nutzer hinzuzufügen, aber das Konto "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" besteht bereits auf diesem Gerät. Trotzdem fortfahren?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" versucht, einen neuen Nutzer für das Konto "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hinzuzufügen. Fortfahren?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Spracheinstellung"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Region auswählen"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Sprache eingeben"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Vorschläge"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Alle Sprachen"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Suche"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 40d2e5b..d572e22 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Αναφορά σφαλμάτων"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Λήψη αναφοράς σφάλματος"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Θα συλλέξει πληροφορίες σχετικά με την τρέχουσα κατάσταση της συσκευής σας και θα τις στείλει μέσω μηνύματος ηλεκτρονικού ταχυδρομείου. Απαιτείται λίγος χρόνος για τη σύνταξη της αναφοράς σφάλματος και την αποστολή της. Κάντε λίγη υπομονή."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Διαδραστική αναφορά"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Χρησιμοποιήστε αυτήν την επιλογή στις περισσότερες περιπτώσεις. Σας επιτρέπει να παρακολουθείτε την πρόοδο της αναφοράς και να εισάγετε περισσότερες λεπτομέρειες σχετικά με το πρόβλημα που αντιμετωπίζετε. Ενδέχεται να παραλείψει ορισμένες ενότητες που δεν χρησιμοποιούνται συχνά και για τις οποίες απαιτείται μεγάλο χρονικό διάστημα για τη δημιουργία αναφορών."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Πλήρης αναφορά"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Λήψη στιγμιότυπου οθόνης για αναφορά σφαλμάτων σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα.</item>
+      <item quantity="one">Λήψη στιγμιότυπου οθόνης για αναφορά σφαλμάτων σε <xliff:g id="NUMBER_0">%d</xliff:g> δευτερόλεπτο.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Λειτουργία σίγασης"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ο ήχος είναι απενεργοποιημένος"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ο ήχος είναι ενεργοποιημένος"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Αγγίξτε για ακύρωση"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Αλλαγή πληκτρολογίου"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Επιλογή πληκτρολογίων"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Εμφάνιση μεθόδου εισαγ."</string>
-    <string name="hardware" msgid="7517821086888990278">"Υλικό"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Να παραμένει στην οθόνη όταν είναι ενεργό το φυσικό πληκτρολόγιο"</string>
+    <string name="hardware" msgid="194658061510127999">"Εμφάνιση εικονικού πληκτρολ."</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Επιλογή διάταξης πληκτρολογίου"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Αγγίξτε για να επιλέξετε διάταξη πληκτρολογίου."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Το "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" προσπαθεί να προσθέσει έναν νέο χρήστη, αλλά έχετε φτάσει το όριο χρηστών."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"Το "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" προσπαθεί να προσθέσει έναν νέο χρήστη, αλλά ο λογαριασμός "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" υπάρχει ήδη σε αυτήν τη συσκευή. Θέλετε να συνεχίσετε ούτως ή άλλως;"</string>
     <string name="user_creation_adding" msgid="3206420861363021392">"Το "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" προσπαθεί να προσθέσει έναν νέο χρήστη για το λογαριασμό "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Θέλετε να συνεχίσετε;"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Προτίμηση γλώσσας"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Προτίμηση περιοχής"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Εισαγ. όνομα γλώσσας"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Προτεινόμενες"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Όλες οι γλώσσες"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Αναζήτηση"</string>
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 80d2efe..ee7dd71 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive report"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Use this under most circumstances. It allows you to track progress of the report and enter more details about the problem. It might omit some less-used sections that take a long time to report."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Full report"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
+      <item quantity="one">Taking screenshot for bug report in <xliff:g id="NUMBER_0">%d</xliff:g> second.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touch to cancel"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Show input method"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string>
+    <string name="hardware" msgid="194658061510127999">"Show virtual keyboard"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Select keyboard layout"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Touch to select a keyboard layout."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the user limit has been reached."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" already exists on this device. Proceed anyway?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user for the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Proceed?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Language preference"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Suggested"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"All languages"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Search"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 80d2efe..ee7dd71 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive report"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Use this under most circumstances. It allows you to track progress of the report and enter more details about the problem. It might omit some less-used sections that take a long time to report."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Full report"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
+      <item quantity="one">Taking screenshot for bug report in <xliff:g id="NUMBER_0">%d</xliff:g> second.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touch to cancel"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Show input method"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string>
+    <string name="hardware" msgid="194658061510127999">"Show virtual keyboard"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Select keyboard layout"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Touch to select a keyboard layout."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the user limit has been reached."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" already exists on this device. Proceed anyway?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user for the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Proceed?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Language preference"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Suggested"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"All languages"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Search"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 80d2efe..ee7dd71 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive report"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Use this under most circumstances. It allows you to track progress of the report and enter more details about the problem. It might omit some less-used sections that take a long time to report."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Full report"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
+      <item quantity="one">Taking screenshot for bug report in <xliff:g id="NUMBER_0">%d</xliff:g> second.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touch to cancel"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Show input method"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string>
+    <string name="hardware" msgid="194658061510127999">"Show virtual keyboard"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Select keyboard layout"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Touch to select a keyboard layout."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the user limit has been reached."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user, but the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" already exists on this device. Proceed anyway?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" is trying to add a new user for the account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Proceed?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Language preference"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Suggested"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"All languages"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Search"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1900e8d..45a0e02 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de errores"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Iniciar informe de errores"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Se recopilará información sobre el estado actual de tu dispositivo, que se enviará por correo. Pasarán unos minutos desde que se inicie el informe de errores hasta que se envíe, por lo que te recomendamos que tengas paciencia."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Informe interactivo"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Usa esta opción en la mayoría de los casos. Te permite ingresar más detalles acerca del problema y realizar un seguimiento del progreso del informe. Es posible que se omitan secciones menos usadas cuyos informes demoran más en completarse."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Informe completo"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Se tomará una captura de pantalla para el informe de errores en <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
+      <item quantity="one">Se tomará una captura de pantalla para el informe de errores en <xliff:g id="NUMBER_0">%d</xliff:g> segundo.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"El sonido está Desactivado"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"El sonido está Activado"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toca para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar el teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Seleccionar teclados"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Mantener en la pantalla cuando el teclado físico está activo"</string>
+    <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona un diseño de teclado"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toca para seleccionar un diseño de teclado."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está intentado agregar un usuario nuevo, pero ya se alcanzó el límite máximo de usuarios."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está intentado agregar un usuario nuevo, pero la cuenta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ya existe en este dispositivo. ¿Deseas continuar de todas formas?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está intentando agregar un usuario nuevo a la cuenta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". ¿Deseas continuar?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferencia de idioma"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferencia de región"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Nombre del idioma"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Sugeridos"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Todos los idiomas"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Búsqueda"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 846b9dc..2f1c4a8 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de error"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Crear informe de errores"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Se recopilará información sobre el estado actual de tu dispositivo y se enviará por correo electrónico. Pasarán unos minutos desde que empiece a generarse el informe de errores hasta que se envíe."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Informe interactivo"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Usa esta opción en la mayoría de los casos. Te permite realizar un seguimiento del progreso de la notificación e introducir más información sobre el problema. Es posible que se omitan algunas secciones menos utilizadas y que requieran más tiempo."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Informe completo"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">La captura de pantalla para el informe de errores se realizará en <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
+      <item quantity="one">La captura de pantalla para el informe de errores se realizará en <xliff:g id="NUMBER_0">%d</xliff:g> segundo.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencio"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"El sonido está desactivado. Activar"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"El sonido está activado. Desactivar"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toca para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Elegir teclados"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Debe seguir en pantalla mientras el teclado físico esté activo"</string>
+    <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona un diseño de teclado"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toca para seleccionar un diseño de teclado."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" quiere añadir un usuario nuevo, pero se ha alcanzado el límite de usuarios."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" quiere añadir un usuario nuevo, pero la cuenta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ya existe en este dispositivo. ¿Quieres continuar de todas formas?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" quiere añadir un usuario nuevo a la cuenta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". ¿Quieres continuar?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferencia de idioma"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferencia de región"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Nombre de idioma"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Sugeridos"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Todos los idiomas"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Buscar"</string>
 </resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 09d031b..3a4f2af 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Veaaruanne"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Veaaruande võtmine"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Nii kogutakse teavet teie seadme praeguse oleku kohta, et saata see meilisõnumina. Enne kui saate veaaruande ära saata, võtab selle loomine natuke aega; varuge kannatust."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interakt. aruanne"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Kasutage seda enamikul juhtudel. See võimaldab jälgida aruande edenemist ja sisestada probleemi kohta täpsemat teavet. Vahele võivad jääda mõned vähem kasutatud jaotised, millest teavitamine võtab rohkem aega."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Täielik aruanne"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Veaaruande jaoks ekraanipildi jäädvustamine <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast.</item>
+      <item quantity="one">Veaaruande jaoks ekraanipildi jäädvustamine <xliff:g id="NUMBER_0">%d</xliff:g> sekundi pärast.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Hääletu režiim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Heli on VÄLJAS"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Heli on SEES"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Puudutage tühistamiseks"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviatuuri muutmine"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vali klaviatuurid"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Sisestusmeetodi kuvamine"</string>
-    <string name="hardware" msgid="7517821086888990278">"Riistvara"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Hoia seda ekraanil, kui füüsiline klaviatuur on aktiivne"</string>
+    <string name="hardware" msgid="194658061510127999">"Virtuaalse klaviatuuri kuvam."</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Klaviatuuri paigutuse valimine"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Puudutage klaviatuuri paigutuse valimiseks."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" üritab lisada uut kasutajat, ent olete jõudnud kasutajate maksimumarvuni."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" üritab lisada uut kasutajat, ent konto "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" on juba seadmes olemas. Kas soovite siiski jätkata?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" üritab lisada uut kasutajat kontole "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Kas soovite jätkata?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Keele-eelistus"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Piirkonnaeelistus"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Sisestage keele nimi"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Soovitatud"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Kõik keeled"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Otsing"</string>
 </resources>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 59cc71e..35d67e9 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Akatsen txostena"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Sortu akatsen txostena"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Gailuaren uneko egoerari buruzko informazioa bilduko da, mezu elektroniko gisa bidaltzeko. Minutu batzuk igaroko dira akatsen txostena sortzen hasten denetik bidaltzeko prest egon arte. Itxaron, mesedez."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Txosten dinamikoa"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Aukera hau erabili beharko zenuke ia beti. Txostenaren jarraipena egin ahal izango duzu eta arazoari buruzko xehetasunak eman ahal izango dituzu. Baliteke gutxitan erabili behar izaten diren atalak ez agertzea, denbora aurrezteko."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Txosten osoa"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Akatsen txostenaren argazkia aterako da <xliff:g id="NUMBER_1">%d</xliff:g> segundo barru.</item>
+      <item quantity="one">Akatsen txostenaren argazkia aterako da <xliff:g id="NUMBER_0">%d</xliff:g> segundo barru.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Isilik modua"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Soinua DESAKTIBATUTA dago"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Soinua AKTIBATUTA dago"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Ukitu bertan behera uzteko"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Aldatu teklatua"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Aukeratu teklatuak"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Erakutsi idazketa-metodoa"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardwarea"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Erakutsi pantailan teklatu fisikoa aktibo dagoen bitartean"</string>
+    <string name="hardware" msgid="194658061510127999">"Erakutsi teklatu birtuala"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Hautatu teklatuaren diseinua"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Ukitu teklatuaren diseinua hautatzeko."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" beste erabiltzaile bat gehitzen saiatzen ari da, baina erabiltzaileen mugara irisi da."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" beste erabiltzaile bat gehitzen saiatzen ari da, baina "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" badago gailuan. Jarraitu nahi duzu halere?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" beste erabiltzaile bat gehitzen saiatzen ari da "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" kontuan. Jarraitu nahi duzu?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Hizkuntza-hobespena"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Lurralde-hobespena"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Adierazi hizkuntza"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Iradokitakoak"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Hizkuntza guztiak"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Bilaketa"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 41c6729..e1adfb9 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"گزارش اشکال"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"گرفتن گزارش اشکال"</string>
     <string name="bugreport_message" msgid="398447048750350456">"این گزارش اطلاعات مربوط به وضعیت دستگاه کنونی شما را جمع‌آوری می‌کند تا به صورت یک پیام ایمیل ارسال شود. از زمان شروع گزارش اشکال تا آماده شدن برای ارسال اندکی زمان می‌برد؛ لطفاً شکیبا باشید."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"گزارش تعاملی"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"در بیشتر شرایط از این گزینه استفاده کنید. به شما امکان ردیابی پیشرفت گزارش و وارد کردن جزئیات بیشتری درباره مشکل را می‌دهد. ممکن است برخی از بخش‌هایی را که کمتر استفاده شده و باعث افزایش طول زمان گزارش می‌شود حذف کند."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"گزارش کامل"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">تا <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دیگر عکس صفحه‌نمایش برای گزارش اشکال گرفته می‌شود.</item>
+      <item quantity="other">تا <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دیگر عکس صفحه‌نمایش برای گزارش اشکال گرفته می‌شود.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"حالت ساکت"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"صدا خاموش است"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"صدا روشن است"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"برای لغو کردن لمس کنید"</string>
     <string name="select_input_method" msgid="8547250819326693584">"تغییر صفحه‌کلید"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"انتخاب صفحه‌کلیدها"</string>
-    <string name="show_ime" msgid="9157568568695230830">"نمایش روش ورودی"</string>
-    <string name="hardware" msgid="7517821086888990278">"سخت‌افزار"</string>
+    <string name="show_ime" msgid="2506087537466597099">"وقتی صفحه‌کلید فیزیکی فعال است این ویرایشگر را روی صفحه نگه‌می‌دارد"</string>
+    <string name="hardware" msgid="194658061510127999">"نمایش صفحه‌کلید مجازی"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"انتخاب طرح‌بندی صفحه‌کلید"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"برای انتخاب یک طرح‌بندی صفحه‌کلید لمس کنید…"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" در تلاش است کاربر جدیدی اضافه کند، اما تعداد کاربران به حداکثر مجاز رسیده است."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" در تلاش است کاربر جدیدی اضافه کند، اما حساب "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" از قبل در این دستگاه وجود دارد. در هر صورت ادامه داده شود؟"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" در تلاش است کاربر جدیدی برای حساب "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" اضافه کند. ادامه می‌دهید؟"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"اولویت‌های زبان"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"اولویت‌های منطقه"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"نام زبان را تایپ کنید"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"پیشنهادشده"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"همه زبان‌ها"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"جستجو"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 70b1bd28..9274b87 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Virheraportti"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Luo virheraportti"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Toiminto kerää tietoja laitteen tilasta ja lähettää ne sähköpostitse. Virheraportti on valmis lähetettäväksi hetken kuluttua - kiitos kärsivällisyydestäsi."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiivinen"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Valitse tämä vaihtoehto useimmissa tapauksissa. Voit seurata raportin etenemistä ja antaa lisätietoja ongelmasta. Tämä vaihtoehto saattaa ohittaa joitakin harvoin käytettyjä osioita, joiden käsittely raportissa kestää kauan."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Koko raportti"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Virheraporttiin otetaan kuvakaappaus <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua.</item>
+      <item quantity="one">Virheraporttiin otetaan kuvakaappaus <xliff:g id="NUMBER_0">%d</xliff:g> sekunnin kuluttua.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Äänetön tila"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Äänet ovat POISSA KÄYTÖSTÄ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Äänet ovat KÄYTÖSSÄ"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Peruuta koskettamalla"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Vaihda näppäimistö"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Valitse näppäimistöt"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Näytä syöttötapa"</string>
-    <string name="hardware" msgid="7517821086888990278">"Laitteisto"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Pidä näytöllä, kun fyysinen näppäimistö on aktiivinen."</string>
+    <string name="hardware" msgid="194658061510127999">"Näytä virtuaalinen näppäimistö"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Valitse näppäimistöasettelu"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Kosketa ja valitse näppäimistöasettelu."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yrittää lisätä uutta käyttäjää, mutta käyttäjiä on jo enimmäismäärä."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yrittää lisätä uutta käyttäjää, mutta tili "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" on jo tässä laitteessa. Jatketaanko silti?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yrittää lisätä uutta käyttäjää tilille "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Jatketaanko?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Kieliasetus"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Alueasetus"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Anna kielen nimi"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Ehdotukset"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Kaikki kielet"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Haku"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 4cbda57..965a83c 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Rapport de bogue"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Créer un rapport de bogue"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme de courriel. Merci de patienter pendant la préparation du rapport de bogue. Cette opération peut prendre quelques instants."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Rapport interactif"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Utilisez cette option dans la plupart des circonstances. Elle vous permet de suivre la progression du rapport et d\'entrer plus de données sur le problème. Certaines sections moins utilisées et dont le remplissage demande beaucoup de temps peuvent être omises."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Rapport complet"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Saisie d\'écran pour le rapport de bogue dans <xliff:g id="NUMBER_1">%d</xliff:g> seconde.</item>
+      <item quantity="other">Saisie d\'écran pour le rapport de bogue dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode silencieux"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Le son est désactivé."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Le son est activé."</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touchez pour annuler"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choisir les claviers"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Afficher le mode d\'entrée"</string>
-    <string name="hardware" msgid="7517821086888990278">"Matériel"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Afficher lorsque le clavier physique est activé"</string>
+    <string name="hardware" msgid="194658061510127999">"Afficher le clavier virtuel"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Sélectionnez la disposition du clavier"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Appuyez ici pour sélectionner une disposition de clavier."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le nombre maximal d\'utilisateurs a été atteint."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" existe déjà sur cet appareil. Continuer?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuer?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Préférences linguistiques"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Préférence régionales"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Entrez la langue"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Suggestions"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Toutes les langues"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Rechercher"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 2daaff4..b0260ef 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Rapport de bug"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Créer un rapport de bug"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme d\'e-mail. Merci de patienter pendant la préparation du rapport de bug. Cette opération peut prendre quelques instants."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Rapport interactif"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Utilisez cette option dans la plupart des circonstances. Elle vous permet de suivre la progression du rapport et de saisir plus d\'informations sur le problème. Certaines sections moins utilisées et dont le remplissage demande beaucoup de temps peuvent être omises."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Rapport complet"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Capture d\'écran pour le rapport de bug dans <xliff:g id="NUMBER_1">%d</xliff:g> seconde</item>
+      <item quantity="other">Capture d\'écran pour le rapport de bug dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode silencieux"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Le son est désactivé."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Le son est activé."</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Appuyer pour annuler"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Sélectionner des claviers"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Afficher mode de saisie"</string>
-    <string name="hardware" msgid="7517821086888990278">"Matériel"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Afficher lorsque le clavier physique est activé"</string>
+    <string name="hardware" msgid="194658061510127999">"Afficher le clavier virtuel"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Sélectionnez la disposition du clavier"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Appuyez ici pour sélectionner une disposition de clavier."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le nombre maximal d\'utilisateurs a été atteint."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" existe déjà sur cet appareil. Continuer ?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur au compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuer ?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Préférences linguistiques"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Préférences régionales"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Saisissez la langue"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Recommandations"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Toutes les langues"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Rechercher"</string>
 </resources>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index a74a013..b2a69fc 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de erros"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Crear informe de erros"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Este informe recompilará información acerca do estado actual do teu dispositivo para enviala en forma de mensaxe de correo electrónico. O informe de erros tardará un pouco en completarse desde o seu inicio ata que estea preparado para enviarse, polo que che recomendamos que teñas paciencia."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Informe interactivo"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Usa esta opción na maioría das circunstancias. Permíteche realizar un seguimento do progreso do informe e introducir máis detalles sobre o problema. Pode que omita algunhas seccións menos usadas para as que se tarda máis en facer o informe."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Informe completo"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Facendo captura de pantalla para informe de erros en <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
+      <item quantity="one">Facendo captura de pantalla para informe de erros en <xliff:g id="NUMBER_0">%d</xliff:g> segundo.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo de silencio"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"O son está desactivado"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O son está activado"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tocar para cancelar o informe de erros"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Seleccionar teclados"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Mostra método de entrada"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Manteno na pantalla mentres o teclado físico estea activo"</string>
+    <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Seleccionar deseño de teclado"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toca para seleccionar un deseño de teclado."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando engadir un usuario novo, pero alcanzouse o límite de usuarios."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando engadir un usuario novo, pero a conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" xa existe neste dispositivo. Queres continuar igualmente?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando engadir un usuario novo á conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Queres continuar?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferencia de idioma"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferencia de rexión"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Escribe o nome"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Suxeridos"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Todos os idiomas"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Buscar"</string>
 </resources>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 97404e9..9848cfb 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"બગ રિપોર્ટ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"બગ રિપોર્ટ લો"</string>
     <string name="bugreport_message" msgid="398447048750350456">"આ, એક ઇ-મેઇલ સંદેશ તરીકે મોકલવા માટે, તમારા વર્તમાન ઉપકરણ સ્થિતિ વિશેની માહિતી એકત્રિત કરશે. એક બગ રિપોર્ટ પ્રારંભ કરીને તે મોકલવા માટે તૈયાર ન થઈ જાય ત્યાં સુધી તેમાં થોડો સમય લાગશે; કૃપા કરીને ધીરજ રાખો."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ક્રિયાપ્રતિક્રિયાત્મક રિપોર્ટ"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"મોટાભાગના સંજોગોમાં આનો ઉપયોગ કરો. તે રિપોર્ટની પ્રગતિને ટ્રૅક કરવા અમે સમસ્યા વિશે વધુ વિગતો દાખલ કરવાની મંજૂરી આપે છે. તે કેટલાંક ઓછા ઉપયોગમાં આવતા વિભાગો કે જે જાણ કરવામાં વધુ સમય લેતા હોય તેને છોડી દઈ શકે છે."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"પૂર્ણ રિપોર્ટ"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">બગ રિપોર્ટ માટે <xliff:g id="NUMBER_1">%d</xliff:g> સેકન્ડમાં સ્ક્રીનશોટ લઈ રહ્યાં છે.</item>
+      <item quantity="other">બગ રિપોર્ટ માટે <xliff:g id="NUMBER_1">%d</xliff:g> સેકન્ડમાં સ્ક્રીનશોટ લઈ રહ્યાં છે.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"સાઇલેન્ટ મોડ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"અવાજ બંધ છે"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ધ્વનિ ચાલુ છે"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"રદ કરવા માટે ટચ કરો"</string>
     <string name="select_input_method" msgid="8547250819326693584">"કીબોર્ડ બદલો"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"કીબોર્ડ્સ પસંદ કરો"</string>
-    <string name="show_ime" msgid="9157568568695230830">"ઇનપુટ પદ્ધતિ બતાવો"</string>
-    <string name="hardware" msgid="7517821086888990278">"હાર્ડવેર"</string>
+    <string name="show_ime" msgid="2506087537466597099">"જ્યારે ભૌતિક કીબોર્ડ સક્રિય હોય ત્યારે તેને સ્ક્રીન પર રાખો"</string>
+    <string name="hardware" msgid="194658061510127999">"વર્ચ્યુઅલ કીબોર્ડ બતાવો"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"કીબોર્ડ લેઆઉટ પસંદ કરો."</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"કીબોર્ડ લેઆઉટ પસંદ કરવા માટે ટચ કરો."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", નવા વપરાશકર્તાને ઉમેરવાનો પ્રયાસ કરી રહી છે, પરંતુ વપરાશકર્તા મર્યાદા સુધી પહોંચી ગયા છો."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", નવા વપરાશકર્તાને ઉમેરવાનો પ્રયાસ કરી રહી છે, પરંતુ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" એકાઉન્ટ પહેલાંથી જ આ ઉપકરણ પર અસ્તિત્વમાં છે. કોઇપણ રીતે આગળ વધીએ?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" એકાઉન્ટ માટે એક નવા વપરાશકર્તાને ઉમેરવાનો પ્રયાસ કરી રહી છે. આગળ વધીએ?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"ભાષા પસંદગી"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"પ્રદેશ પસંદગી"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"ભાષાનું નામ ટાઇપ કરો"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"સૂચવેલા"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"બધી ભાષાઓ"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"શોધ"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 39bc701..39608cb 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"बग रिपोर्ट"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"बग रिपोर्ट प्राप्त करें"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ईमेल संदेश के रूप में भेजने के लिए, इसके द्वारा आपके डिवाइस की वर्तमान स्थिति के बारे में जानकारी एकत्र की जाएगी. बग रिपोर्ट प्रारंभ करने से लेकर भेजने के लिए तैयार होने तक कुछ समय लगेगा; कृपया धैर्य रखें."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"सहभागी रिपोर्ट"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"अधिकांश परिस्‍थितियों में इसका उपयोग करें. यह आपको रिपोर्ट की प्रगति ट्रैक करने देता है और समस्‍या के बारे में अधिक विवरण डालने देता है. यह आपको ऐसे कम उपयोग किए गए अनुभाग मिटाने दे सकता है जिनकी रिपोर्ट करने में अधिक समय लगता है."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"पूर्ण रिपोर्ट"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">बग रिपोर्ट के लिए <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में स्‍क्रीनशॉट लिया जा रहा है.</item>
+      <item quantity="other">बग रिपोर्ट के लिए <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में स्‍क्रीनशॉट लिया जा रहा है.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"मौन मोड"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ध्‍वनि बंद है"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ध्‍वनि चालू है"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"रद्द करने के लिए स्पर्श करें"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदलें"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड चुनें"</string>
-    <string name="show_ime" msgid="9157568568695230830">"इनपुट विधि दिखाएं"</string>
-    <string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
+    <string name="show_ime" msgid="2506087537466597099">"भौतिक कीबोर्ड के सक्रिय होने के दौरान इसे स्‍क्रीन पर बनाए रखें"</string>
+    <string name="hardware" msgid="194658061510127999">"वर्चुअल कीबोर्ड दिखाएं"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"कीबोर्ड लेआउट को चुनें"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"कीबोर्ड लेआउट का चयन करने के लिए स्‍पर्श करें."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" नए उपयोगकर्ता को जोड़ने का प्रयास कर रहा है, लेकिन उपयोगकर्ता की सीमा पूरी हो गई है."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" नए उपयोगकर्ता को जोड़ने का प्रयास कर रहा है, लेकिन "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" खाता इस डिवाइस पर पहले से मौजूद है. फिर भी आगे बढ़ें?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" इस "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" खाते के लिए नया उपयोगकर्ता जोड़ने का प्रयास कर रहा है. आगे बढ़ें?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"भाषा प्राथमिकता"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"क्षेत्र प्राथमिकता"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"भाषा का नाम लिखें"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"सुझाए गए"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"सभी भाषाएं"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"खोजें"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index fbb347f..2584260 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -212,15 +212,16 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izvješće o bugovima"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Izvješće o programskoj pogrešci"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Time će se prikupiti podaci o trenutačnom stanju vašeg uređaja koje ćete nam poslati u e-poruci. Za pripremu izvješća o programskoj pogrešci potrebno je nešto vremena pa vas molimo za strpljenje."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktivno izvješće"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"To možete upotrebljavati u većini slučajeva. Moći ćete pratiti izradu izvješća i unijeti više pojedinosti o problemu. Mogu se izostaviti neki odjeljci koji se upotrebljavaju rjeđe i produljuju izradu izvješća."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Potpuno izvješće"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Izrada snimke zaslona za izvješće o programskoj pogrešci za <xliff:g id="NUMBER_1">%d</xliff:g> sekundu.</item>
+      <item quantity="few">Izrada snimke zaslona za izvješće o programskoj pogrešci za <xliff:g id="NUMBER_1">%d</xliff:g> sekunde.</item>
+      <item quantity="other">Izrada snimke zaslona za izvješće o programskoj pogrešci za <xliff:g id="NUMBER_1">%d</xliff:g> sekundi.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Bešumni način"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je isključen"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je uključen"</string>
@@ -1056,8 +1057,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Dodirnite da biste otkazali"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promjena tipkovnice"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Odaberi tipkovnice"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Prikaz način unosa"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardver"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Zadržava se na zaslonu dok je fizička tipkovnica aktivna"</string>
+    <string name="hardware" msgid="194658061510127999">"Prikaži virtualnu tipkovnicu"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Odaberite izgled tipkovnice"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dodirnite za odabir izgleda tipkovnice."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1549,4 +1550,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava dodati novog korisnika, no dosegnuto je ograničenje broja korisnika."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava dodati novog korisnika, ali račun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" već postoji na ovom uređaju. Želite li ipak nastaviti?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava dodati novog korisnika za račun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Želite li nastaviti?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Postavke jezika"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Postavke regije"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Unesite 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">"Pretraži"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 569e725..a5d8f14 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Programhiba bejelentése"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Hibajelentés készítése"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ezzel információt fog gyűjteni az eszköz jelenlegi állapotáról, amelyet a rendszer e-mailben fog elküldeni. Kérjük, legyen türelemmel, amíg a hibajelentés elkészül, és küldhető állapotba kerül."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktív jelentés"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Ezt használja a legtöbb esetben. Segítségével nyomon követheti a jelentés folyamatát, és további információkat kaphat a problémáról. A folyamat során kimaradhatnak az olyan kevésbé használt részek, amelyek jelentése túl sok időt igényel."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Teljes jelentés"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Képernyőkép készítése a hibajelentéshez <xliff:g id="NUMBER_1">%d</xliff:g> másodpercen belül.</item>
+      <item quantity="one">Képernyőkép készítése a hibajelentéshez <xliff:g id="NUMBER_0">%d</xliff:g> másodpercen belül.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Néma üzemmód"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Hang kikapcsolva"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Hang bekapcsolva"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"A visszavonáshoz érintse meg"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Billentyűzet megváltoztatása"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Billentyűzetek kiválasztása"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Beviteli mód megjelenítése"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardver"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Maradjon a képernyőn, amíg a billentyűzet aktív"</string>
+    <string name="hardware" msgid="194658061510127999">"Virtuális billentyűzet"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Válasszon billentyűzetkiosztást"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Érintse meg az egyik billentyűzetkiosztás kiválasztásához."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"A(z) "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" alkalmazás egy új felhasználót szeretne megadni, azonban Ön elérte a felhasználók számára vonatkozó felső korlátot."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"A(z) "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" alkalmazás egy új felhasználót szeretne megadni, de a(z) "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" fiók már létezik ezen az eszközön. Ettől függetlenül is folytatja?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392">"A(z) "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" alkalmazás egy új felhasználót szeretne hozzáadni a(z) "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" fiókhoz. Folytatja a műveletet?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Nyelvi beállítás"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Régió beállítása"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Adja meg a nyelvet"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Javasolt"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Minden nyelv"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Keresés"</string>
 </resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index cbe058e..1149ec1 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Վրիպակի զեկույց"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Գրել սխալի զեկույց"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Սա տեղեկություններ կհավաքագրի ձեր սարքի առկա կարգավիճակի մասին և կուղարկի այն էլեկտրոնային նամակով: Որոշակի ժամանակ կպահանջվի վրիպակի մասին զեկուցելու պահից սկսած մինչ ուղարկելը: Խնդրում ենք փոքր-ինչ համբերատար լինել:"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Ինտերակտիվ զեկույց"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Հիմնականում օգտագործեք այս տարբերակը: Այն ձեզ թույլ է տալիս հետագծել զեկույցի ստեղծման գործընթացը և խնդրի մասին լրացուցիչ տեղեկություններ մուտքագրել: Կարող է բաց թողնել որոշ քիչ օգտագործվող բաժինները, որոնց ստեղծումը երկար է տևում:"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Ամբողջական զեկույց"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Վրիպակի զեկույցի համար էկրանի պատկերի լուսանկարումը կատարվելու է <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:</item>
+      <item quantity="other">Վրիպակի զեկույցի համար էկրանի պատկերի լուսանկարումը կատարվելու է <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Անձայն ռեժիմ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ձայնը անջատված է"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ձայնը միացված է"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Հպեք՝ չեղարկելու համար"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Փոխել ստեղնաշարը"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Ընտրել ստեղնաշար"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Ցուցադրել մուտքագրման եղանակը"</string>
-    <string name="hardware" msgid="7517821086888990278">"Սարքաշար"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Պահել էկրանին մինչդեռ ֆիզիկական ստեղնաշարն ակտիվ է"</string>
+    <string name="hardware" msgid="194658061510127999">"Ցույց տալ վիրտուալ ստեղնաշարը"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Ընտրեք ստեղնաշարի դիրքը"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Հպեք` ստեղնաշարի դիրքը ընտրելու համար:"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՈՒՓՔԵւՕՖ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" հավելվածը փորձում է նոր օգտվող ավելացնել, սակայն օգտվողների քանակի սահմանաչափը լրացել է:"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" հավելվածը փորձում է նոր օգտվող ավելացնել, սակայն "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" հաշիվն այս սարքում արդեն գոյություն ունի: Շարունակե՞լ:"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" հավելվածը փորձում է "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" հաշվի համար նոր օգտվող ավելացնել: Շարունակե՞լ:"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Նախընտրելի լեզու"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Նախընտրելի տարածաշրջան"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Մուտքագրեք լեզուն"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Առաջարկներ"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Բոլոր լեզուները"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Որոնում"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 15efd94..37084e3 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Laporan bug"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan bug"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpulkan informasi status perangkat Anda saat ini, untuk dikirimkan sebagai pesan email. Harap bersabar, mungkin perlu waktu untuk memulai laporan bug hingga siap dikirim."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Laporan interaktif"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Gunakan ini di berbagai keadaan. Ini memungkinkan Anda melacak kemajuan laporan dan memasukkan detail masalah selengkapnya. Mungkin menghilangkan beberapa bagian yang jarang digunakan dan yang perlu waktu lama untuk dilaporkan."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Laporan lengkap"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Mengambil tangkapan layar untuk laporan bug dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik.</item>
+      <item quantity="one">Mengambil tangkapan layar untuk laporan bug dalam <xliff:g id="NUMBER_0">%d</xliff:g> detik.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode senyap"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Suara MATI"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Suara AKTIF"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Sentuh untuk membatalkan"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Ubah keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pilih keyboard"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Tampilkan metode masukan"</string>
-    <string name="hardware" msgid="7517821086888990278">"Perangkat Keras"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Pertahankan di layar jika keyboard fisik masih aktif"</string>
+    <string name="hardware" msgid="194658061510127999">"Tampilkan keyboard virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pilih tata letak keyboard"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Sentuh untuk memilih tata letak keyboard."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mencoba menambahkan pengguna baru, tetapi batas jumlah pengguna telah tercapai."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mencoba menambahkan pengguna baru, tetapi akun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" sudah ada di perangkat. Tetap lanjutkan?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mencoba menambahkan pengguna baru untuk akun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Lanjutkan?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferensi bahasa"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferensi wilayah"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Ketik nama bahasa"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Disarankan"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Semua bahasa"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Telusuri"</string>
 </resources>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 88d58b0..662d1dd 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Villutilkynning"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Útbúa villutilkynningu"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Þetta safnar upplýsingum um núverandi stöðu tækisins til að senda með tölvupósti. Það tekur smástund frá því villutilkynningin er ræst og þar til hún er tilbúin til sendingar – sýndu biðlund."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Gagnvirk skýrsla"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Þú getur notað þetta í flestum tilvikum. Með þessu móti geturðu fylgst með framgangi skýrslunnar og slegið inn viðbótarupplýsingar um vandamálið. Hugsanlegt er að lítið notuðum hlutum verði sleppt til að spara tíma."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Heildarskýrsla"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Tekur skjámynd fyrir villutilkynningu eftir <xliff:g id="NUMBER_1">%d</xliff:g> sekúndu.</item>
+      <item quantity="other">Tekur skjámynd fyrir villutilkynningu eftir <xliff:g id="NUMBER_1">%d</xliff:g> sekúndur.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Hljóðlaus stilling"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"SLÖKKT er á hljóði"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"KVEIKT er á hljóði"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Snertu til að hætta við"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Skipta um lyklaborð"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Velja lyklaborð"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Sýna innsláttaraðferð"</string>
-    <string name="hardware" msgid="7517821086888990278">"Vélbúnaður"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Haltu því á skjánum meðan vélbúnaðarlyklaborðið er virkt"</string>
+    <string name="hardware" msgid="194658061510127999">"Sýna sýndarlyklaborð"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Veldu lyklaskipan"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Snertu til að velja lyklaskipan."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCDÐEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" er að reyna að bæta við nýjum notanda, en notandahámarkinu hefur þegar verið náð."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" er að reyna að bæta við nýjum notanda, en reikningurinn "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" er nú þegar til á þessu tæki. Halda samt áfram?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" er að reyna að bæta nýjum notanda við reikninginn "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Halda áfram?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Val tungumáls"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Svæðisval"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Sláðu inn heiti tungumáls"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Tillögur"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Öll tungumál"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Leita"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index da34b35..230f3e0 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Segnalazione di bug"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Apri segnalazione bug"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Verranno raccolte informazioni sullo stato corrente del dispositivo che saranno inviate sotto forma di messaggio email. Passerà un po\' di tempo prima che la segnalazione di bug aperta sia pronta per essere inviata; ti preghiamo di avere pazienza."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Rapporto interattivo"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Utilizza questa opzione nella maggior parte dei casi. Ti consente di monitorare l\'avanzamento del rapporto e di inserire maggiori dettagli relativi al problema. Potrebbero essere omesse alcune sezioni meno utilizzate il cui inserimento nel rapporto richiede molto tempo."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Rapporto completo"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Lo screenshot per la segnalazione di bug verrà acquisito tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi.</item>
+      <item quantity="one">Lo screenshot per la segnalazione di bug verrà acquisito tra <xliff:g id="NUMBER_0">%d</xliff:g> secondo.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modalità silenziosa"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Audio non attivo"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Audio attivo"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tocca per annullare"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambia tastiera"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Scegli tastiera"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Mostra metodo immissione"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Tieni sullo schermo quando è attiva la tastiera fisica"</string>
+    <string name="hardware" msgid="194658061510127999">"Mostra tastiera virtuale"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Seleziona layout tastiera"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Tocca per selezionare un layout di tastiera."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sta cercando di aggiungere un nuovo utente, ma è stato raggiunto il limite massimo di utenti."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sta cercando di aggiungere un nuovo utente, ma l\'account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" esiste già su questo dispositivo. Continuare comunque?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sta cercando di aggiungere un nuovo utente per l\'account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuare?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferenza lingua"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Area geografica preferita"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Digita nome lingua"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Suggerite"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Tutte le lingue"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Cerca"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 54c1fb1..0278191 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -213,15 +213,17 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"דיווח על באג"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"שלח דיווח על באג"</string>
     <string name="bugreport_message" msgid="398447048750350456">"פעולה זו תאסוף מידע על מצב המכשיר הנוכחי שלך על מנת לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת דיווח הבאג ועד לשליחת ההודעה בפועל. אנא המתן בסבלנות."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"דוח אינטראקטיבי"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"השתמש באפשרות זו ברוב המקרים. היא מאפשרת לך לעקוב אחר התקדמות הדוח ולהזין פרטים נוספים על הבעיה. היא עשויה להשמיט כמה קטעים שנמצאים פחות בשימוש ואשר יצירת הדיווח עליהם נמשכת זמן רב."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"דוח מלא"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="two">יוצר צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות.</item>
+      <item quantity="many">יוצר צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות.</item>
+      <item quantity="other">יוצר צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות.</item>
+      <item quantity="one">יוצר צילום מסך לדוח על באג בעוד <xliff:g id="NUMBER_0">%d</xliff:g> שנייה.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"מצב שקט"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"הקול כבוי"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"קול מופעל"</string>
@@ -1063,8 +1065,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"גע כדי לבטל"</string>
     <string name="select_input_method" msgid="8547250819326693584">"שינוי מקלדת"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"בחר מקלדות"</string>
-    <string name="show_ime" msgid="9157568568695230830">"הצג שיטת קלט"</string>
-    <string name="hardware" msgid="7517821086888990278">"חומרה"</string>
+    <string name="show_ime" msgid="2506087537466597099">"השאר אותו במסך בזמן שהמקלדת הפיזית פעילה"</string>
+    <string name="hardware" msgid="194658061510127999">"הצג מקלדת וירטואלית"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"בחירת פריסת מקלדת"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"גע כדי לבחור פריסת מקלדת."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1567,4 +1569,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" מנסה להוסיף משתמש חדש, אך מכסת המשתמשים כבר מלאה."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" מנסה להוסיף משתמש חדש, אך החשבון "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" כבר קיים במכשיר זה. להמשיך בכל זאת?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" מנסה להוסיף משתמש חדש לחשבון "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". להמשיך?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"העדפת שפה"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"העדפת אזור"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"הקלד שם שפה"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"הצעות"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"כל השפות"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"חיפוש"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 35dbd24..a92a800 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"バグレポート"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"バグレポートを取得"</string>
     <string name="bugreport_message" msgid="398447048750350456">"現在の端末の状態に関する情報が収集され、その内容がメールで送信されます。バグレポートが開始してから送信可能な状態となるまでには多少の時間がかかりますのでご了承ください。"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"対話型レポート"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"ほとんどの場合はこのオプションを使用します。レポートの進行状況を追跡し、問題についての詳細情報を確認することができます。レポート作成に時間がかかってもあまり使用されないセクションは省略されることがあります。"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"完全レポート"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> 秒後にバグレポートのスクリーンショットが作成されます。</item>
+      <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> 秒後にバグレポートのスクリーンショットが作成されます。</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"マナーモード"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"サウンドOFF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"サウンドON"</string>
@@ -246,13 +246,13 @@
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMSメッセージの送信と表示"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"ストレージ"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"端末上の写真、メディア、ファイルへのアクセス"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"端末内の写真、メディア、ファイルへのアクセス"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"マイク"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"音声の録音"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"カメラ"</string>
-    <string name="permgroupdesc_camera" msgid="3250611594678347720">"写真の撮影と動画の記録"</string>
+    <string name="permgroupdesc_camera" msgid="3250611594678347720">"写真と動画の撮影"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
-    <string name="permgroupdesc_phone" msgid="6234224354060641055">"通話の発信と管理"</string>
+    <string name="permgroupdesc_phone" msgid="6234224354060641055">"電話の発信と管理"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"ボディーセンサー"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"バイタルサインに関するセンサーデータへのアクセス"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ウィンドウコンテンツの取得"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"キャンセルするにはタップしてください"</string>
     <string name="select_input_method" msgid="8547250819326693584">"キーボードの変更"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"キーボードの選択"</string>
-    <string name="show_ime" msgid="9157568568695230830">"スクリーンキーボードを表示する"</string>
-    <string name="hardware" msgid="7517821086888990278">"ハードウェア"</string>
+    <string name="show_ime" msgid="2506087537466597099">"物理キーボードが有効になっている間は、画面に表示されます"</string>
+    <string name="hardware" msgid="194658061510127999">"仮想キーボードの表示"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"キーボードレイアウトの選択"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"タップしてキーボードレイアウトを選択してください。"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" で新しいユーザーを追加しようとしていますが、ユーザー数の上限に達しています。"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" で新しいユーザーを追加しようとしていますが、アカウント "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" は既にこの端末に存在します。続行しますか?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" でアカウント "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" に新しいユーザーを追加しようとしています。続行しますか?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"言語設定"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"地域設定"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"言語名を入力"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"言語の候補"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"すべての言語"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"検索"</string>
 </resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 864e495..3f5ad1f 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ხარვეზის შესახებ ანგარიში"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"შექმენით შეცდომის ანგარიში"</string>
     <string name="bugreport_message" msgid="398447048750350456">"იგი შეაგროვებს ინფორმაციას თქვენი მოწყობილობის ამჟამინდელი მდგომარეობის შესახებ, რათა ის ელფოსტის შეტყობინების სახით გააგზავნოს. ხარვეზის ანგარიშის მომზადებასა და შეტყობინების გაგზავნას გარკვეული დრო სჭირდება. გთხოვთ, მოითმინოთ."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ინტერაქტიული ანგარიში"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"გამოიყენეთ ეს ვარიანტი შემთხვევათა უმეტესობაში. ის საშუალებას მოგცემთ, თვალი მიადევნოთ ანგარიშის პროგრესს და პრობლემის შესახებ მეტი დეტალი შეიყვანოთ. ამ ვარიანტის არჩევის შემთხვევაში, შეიძლება მოხდეს ზოგიერთი ნაკლებად გამოყენებადი სექციის გამოტოვება, რომელთა შესახებ მოხსენებასაც დიდი დრო სჭირდება."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"სრული ანგარიში"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">ხარვეზის შესახებ ანგარიშის ეკრანის ანაბეჭდის გადაღება მოხდება <xliff:g id="NUMBER_1">%d</xliff:g> წამში.</item>
+      <item quantity="one">ხარვეზის შესახებ ანგარიშის ეკრანის ანაბეჭდის გადაღება მოხდება <xliff:g id="NUMBER_0">%d</xliff:g> წამში.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"ჩუმი რეჟიმი"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ხმა გამორთულია"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ხმა ჩართულია"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"შეეხეთ გასაუქმებლად"</string>
     <string name="select_input_method" msgid="8547250819326693584">"კლავიატურის შეცვლა"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"კლავიატურების არჩევა"</string>
-    <string name="show_ime" msgid="9157568568695230830">"შეყვანის მეთოდის ჩვენება"</string>
-    <string name="hardware" msgid="7517821086888990278">"მოწყობილობა"</string>
+    <string name="show_ime" msgid="2506087537466597099">"აქტიური ფიზიკური კლავიატურისას ეკრანზე შენარჩუნება"</string>
+    <string name="hardware" msgid="194658061510127999">"ვირტუალური კლავიატურის ჩვენება"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"შეარჩიეთ კლავიატურის განლაგება."</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"კლავიატურის განლაგების შესარჩევად შეეხეთ."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ახალი მომხმარებლის დამატებას ცდილობს, მაგრამ მიღწეულია მომხმარებლების ლიმიტი."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ახალი მომხმარებლის დამატებას ცდილობს, მაგრამ ანგარიში — "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" უკვე არსებობს ამ მოწყობილობაში. მაინც გსურთ გაგრძელება?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ცდილობს, ანგარიშს — "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ახალი მომხმარებელი დაუმატოს. გსურთ გაგრძელება?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"ენის პარამეტრები"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"რეგიონის პარამეტრები"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"აკრიფეთ ენის სახელი"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"რეკომენდებული"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ყველა ენა"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"ძიება"</string>
 </resources>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 8062208..25de46b 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Вирус туралы хабарлау"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Қате туралы есеп құру"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Құрылғының қазіргі күйі туралы ақпаратты жинап, электрондық хабармен жібереді. Есеп әзір болғанша біраз уақыт кетеді, шыдай тұрыңыз."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивті есеп"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Мұны жағдайлардың көпшілігінде пайдаланыңыз. Ол есептің орындалу барысын бақылауға және мәселе туралы қосымша мәліметтер енгізуге мүмкіндік береді. Ол есеп беруге ұзақ уақыт кететін кейбір азырақ пайдаланылатын бөлімдерді өткізіп жіберуі мүмкін."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Толық есеп"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> секундтан кейін қате туралы есептің скриншоты түсіріледі.</item>
+      <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> секундтан кейін қате туралы есептің скриншоты түсіріледі.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Үнсіз режимі"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Дыбыс ӨШІРУЛІ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Дыбыс ҚОСУЛЫ"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Бас тарту үшін түртіңіз"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Пернетақтаны өзгерту"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Пернетақталарды таңдау"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Енгізу әдісін көрсету"</string>
-    <string name="hardware" msgid="7517821086888990278">"Компьютерлік жабдық"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Физикалық пернетақта белсенді кезде оны экранда ұстау"</string>
+    <string name="hardware" msgid="194658061510127999">"Виртуалды пернетақтаны көрсету"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Пернетақта орналасуын таңдау"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Пернетақта орналасуын таңдау үшін түртіңіз."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңа пайдаланушыны қосуға тырысуда, бірақ пайдаланушылар саны шегіне жетті."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңа пайдаланушыны қосуға тырысуда, бірақ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" есептік жазбасы осы құрылғыда әлдеқашан бар. Бәрібір жалғастыру керек пе?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" есептік жазбасы үшін жаңа пайдаланушыны қосуға тырысуда. Жалғастыру керек пе?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Тіл параметрі"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Аймақ параметрі"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Тіл атауын теріңіз"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Ұсынылған"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Барлық тілдер"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Іздеу"</string>
 </resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index db743b5..6b51f61 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"របាយការណ៍​កំហុស"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"យក​របាយការណ៍​កំហុស"</string>
     <string name="bugreport_message" msgid="398447048750350456">"វា​នឹង​​ប្រមូល​ព័ត៌មាន​អំពី​ស្ថានភាព​ឧបករណ៍​របស់​អ្នក ដើម្បី​ផ្ញើ​ជា​សារ​អ៊ីមែល។ វា​នឹង​ចំណាយ​ពេល​តិច​ពី​ពេល​ចាប់ផ្ដើម​របាយការណ៍​រហូត​ដល់​ពេល​វា​រួចរាល់​ដើម្បី​ផ្ញើ សូម​អត់ធ្មត់។"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"របាយការណ៍អន្តរកម្ម"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"ប្រើវាគ្រប់កាលៈទេសៈទាំងអស់។ វាអនុញ្ញាតឲ្យអ្នកតាមដានដំណើរការនៃរបាយការណ៍ និងចូលទៅព័ត៌មានលម្អិតបន្ថែមអំពីបញ្ហានេះ។ វាអាចនឹងលុបផ្នែកមួយចំនួនដែលមិនសូវប្រើចេញ ដែលធ្វើឲ្យចំណាយពេលយូរក្នុងការរាយការណ៍។"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"របាយការណ៍ពេញលេញ"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">នឹងថតរូបអេក្រង់សម្រាប់របាយការណ៍កំហុសក្នុងរយៈពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទីទៀត។</item>
+      <item quantity="one">នឹងថតរូបអេក្រង់សម្រាប់របាយការណ៍កំហុសក្នុងរយៈពេល <xliff:g id="NUMBER_0">%d</xliff:g> វិនាទីទៀត។</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"របៀប​ស្ងាត់"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"បិទ​សំឡេង"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"បើក​សំឡេង"</string>
@@ -1051,8 +1051,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ប៉ះដើម្បីបោះបង់"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ប្ដូរ​ក្ដារចុច"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ជ្រើស​ក្ដារចុច"</string>
-    <string name="show_ime" msgid="9157568568695230830">"បង្ហាញ​វិធី​សាស្ត្រ​បញ្ចូល"</string>
-    <string name="hardware" msgid="7517821086888990278">"ផ្នែក​រឹង"</string>
+    <string name="show_ime" msgid="2506087537466597099">"ទុកវានៅលើអេក្រង់ខណៈពេលក្តារចុចពិតប្រាកដកំពុងសកម្ម"</string>
+    <string name="hardware" msgid="194658061510127999">"បង្ហាញក្ដារចុចនិម្មិត"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ជ្រើស​ប្លង់​ក្ដារ​ចុច"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ប៉ះ ​ដើម្បី​ជ្រើស​ប្លង់​​ក្ដារចុច។"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1533,4 +1533,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" កំពុងព្យាយាមបន្ថែមអ្នកប្រើថ្មី ប៉ុន្តែបានឈានដល់ចំនួនកំណត់អ្នកប្រើហើយ។"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" កំពុងព្យាយាមបន្ថែមអ្នកប្រើថ្មី ប៉ុន្តែគណនី "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" មានរួចទៅហើយនៅលើឧបករណ៍នេះ។ បន្តទោះយ៉ាងណាក៏ដោយ?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" កំពុងព្យាយាមបន្ថែមអ្នកប្រើថ្មីសម្រាប់គណនី "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"។ បន្តឬ?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"ចំណូល​ចិត្ត​ភាសា"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"ចំណូលចិត្តតំបន់"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"វាយបញ្ចូលឈ្មោះភាសា"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"បាន​ស្នើ"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ភាសាទាំងអស់"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"ស្វែងរក"</string>
 </resources>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index cde0901..d85d3984 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ದೋಷದ ವರದಿ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ದೋಷ ವರದಿ ರಚಿಸಿ"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ನಿಮ್ಮ ಸಾಧನದ ಪ್ರಸ್ತುತ ಸ್ಥಿತಿಯ ಕುರಿತು ಮಾಹಿತಿಯನ್ನು ಸಂಗ್ರಹಿಸಿಕೊಳ್ಳುವುದರ ಜೊತೆ ಇ-ಮೇಲ್ ರೂಪದಲ್ಲಿ ನಿಮಗೆ ರವಾನಿಸುತ್ತದೆ. ಇದು ದೋಷ ವರದಿಯನ್ನು ಪ್ರಾರಂಭಿಸಿದ ಸಮಯದಿಂದ ಅದನ್ನು ಕಳುಹಿಸುವವರೆಗೆ ಸ್ವಲ್ಪ ಸಮಯವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ; ದಯವಿಟ್ಟು ತಾಳ್ಮೆಯಿಂದಿರಿ."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ಪರಸ್ಪರ ಸಂವಹನ ವರದಿ"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"ಹೆಚ್ಚಿನ ಸಂದರ್ಭಗಳಲ್ಲಿ ಇದನ್ನು ಬಳಸಿ. ಇದು ವರದಿಯ ಪ್ರಗತಿಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು ಮತ್ತು ಸಮಸ್ಯೆ ಕುರಿತು ಹೆಚ್ಚಿನ ವಿವರಗಳನ್ನು ನಮೂದಿಸಲು ಅನುಮತಿಸುತ್ತದೆ. ಇದು ವರದಿ ಮಾಡಲು ಹೆಚ್ಚು ಸಮಯ ತೆಗೆದುಕೊಳ್ಳುವಂತಹ ಕೆಲವು ಕಡಿಮೆ ಬಳಸಲಾದ ವಿಭಾಗಗಳನ್ನು ತ್ಯಜಿಸಬಹುದು."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"ಪೂರ್ಣ ವರದಿ"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">ಬಗ್ ವರದಿ ಮಾಡಲು <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ.</item>
+      <item quantity="other">ಬಗ್ ವರದಿ ಮಾಡಲು <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"ಶಾಂತ ಮೋಡ್"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ಶಬ್ಧ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ಶಬ್ಧ ಆನ್ ಆಗಿದೆ"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ರದ್ದುಗೊಳಿಸಲು ಸ್ಪರ್ಶಿಸಿ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ಕೀಬೋರ್ಡ್ ಬದಲಿಸಿ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
-    <string name="show_ime" msgid="9157568568695230830">"ಇನ್‌ಪುಟ್‌ ವಿಧಾನವನ್ನು ತೋರಿಸು"</string>
-    <string name="hardware" msgid="7517821086888990278">"ಹಾರ್ಡ್‌ವೇರ್"</string>
+    <string name="show_ime" msgid="2506087537466597099">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ ಸಕ್ರಿಯವಾಗಿರುವಾಗ ಅದನ್ನು ಪರದೆಯ ಮೇಲೆ ಇರಿಸಿಕೊಳ್ಳಿ"</string>
+    <string name="hardware" msgid="194658061510127999">"ವರ್ಚ್ಯುಯಲ್ ಕೀಬೋರ್ಡ್ ತೋರಿಸು"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಆಯ್ಕೆ ಮಾಡಲು ಸ್ಪರ್ಶಿಸಿ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತಿದ್ದಾರೆ, ಆದರೆ ಬಳಕೆದಾರರ ಮಿತಿಯನ್ನು ತಲುಪಲಾಗಿದೆ."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತಿದ್ದಾರೆ, ಆದರೆ ಈ ಸಾಧನದಲ್ಲಿ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ಖಾತೆ ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ. ಹೇಗಾದರೂ ಮುಂದುವರೆಯುವುದೇ?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ಖಾತೆಗೆ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಲು "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ಪ್ರಯತ್ನಿಸುತ್ತಿದ್ದಾರೆ. ಮುಂದುವರೆಯುವುದೇ?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"ಭಾಷೆಯ ಪ್ರಾಶಸ್ತ್ಯ"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"ಪ್ರದೇಶ ಪ್ರಾಶಸ್ತ್ಯ"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"ಭಾಷೆ ಹೆಸರನ್ನು ಟೈಪ್ ಮಾಡಿ"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"ಸಲಹೆ ಮಾಡಿರುವುದು"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ಎಲ್ಲಾ ಭಾಷೆಗಳು"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"ಹುಡುಕು"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index f3c6c69..1a92e93 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"버그 신고"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"버그 신고"</string>
     <string name="bugreport_message" msgid="398447048750350456">"현재 기기 상태에 대한 정보를 수집하여 이메일 메시지로 전송합니다. 버그 신고를 시작하여 전송할 준비가 되려면 약간 시간이 걸립니다."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"대화형 보고서"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"대부분의 경우 이 옵션을 사용합니다. 신고 진행 상황을 추적할 수 있고 문제에 대한 세부정보를 입력할 수 있습니다. 신고하기에 시간이 너무 오래 걸리고 사용 빈도가 낮은 일부 섹션을 생략할 수 있습니다."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"전체 보고서"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">버그 신고 스크린샷을 <xliff:g id="NUMBER_1">%d</xliff:g>초 후에 찍습니다.</item>
+      <item quantity="one">버그 신고 스크린샷을 <xliff:g id="NUMBER_0">%d</xliff:g>초 후에 찍습니다.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"무음 모드"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"소리 꺼짐"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"소리 켜짐"</string>
@@ -238,23 +238,23 @@
     <string name="user_owner_label" msgid="2804351898001038951">"개인"</string>
     <string name="managed_profile_label" msgid="6260850669674791528">"직장"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"주소록"</string>
-    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"주소록 액세스"</string>
+    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"주소록에 접근할 수 있도록"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"위치"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"이 기기의 위치에 액세스"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"이 기기의 위치정보에 접근할 수 있도록"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"캘린더"</string>
-    <string name="permgroupdesc_calendar" msgid="3889615280211184106">"캘린더 액세스"</string>
+    <string name="permgroupdesc_calendar" msgid="3889615280211184106">"일정에 접근할 수 있도록"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
-    <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS 메시지 전송 및 보기"</string>
+    <string name="permgroupdesc_sms" msgid="4656988620100940350">"문자 메시지를 보내고 확인할 수 있도록"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"저장"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"기기 사진, 미디어, 파일 액세스"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"기기 사진, 미디어, 파일에 접근할 수 있도록"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"마이크"</string>
-    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"오디오 녹음"</string>
+    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"오디오를 녹음할 수 있도록"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"카메라"</string>
-    <string name="permgroupdesc_camera" msgid="3250611594678347720">"사진 및 동영상 촬영"</string>
+    <string name="permgroupdesc_camera" msgid="3250611594678347720">"사진 및 동영상을 촬영할 수 있도록"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"전화"</string>
-    <string name="permgroupdesc_phone" msgid="6234224354060641055">"전화 걸기 및 관리"</string>
+    <string name="permgroupdesc_phone" msgid="6234224354060641055">"통화 상태를 관리하거나 전화를 걸 수 있도록"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"신체 센서"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"생체 신호에 관한 센서 데이터에 액세스"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"생체 신호에 관한 센서 데이터에 접근할 수 있도록"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"창 콘텐츠 가져오기"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"상호작용 중인 창의 콘텐츠를 검사합니다."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"터치하여 탐색 사용"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"취소하려면 터치하세요."</string>
     <string name="select_input_method" msgid="8547250819326693584">"키보드 변경"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"키보드 선택"</string>
-    <string name="show_ime" msgid="9157568568695230830">"입력 방법 표시"</string>
-    <string name="hardware" msgid="7517821086888990278">"하드웨어"</string>
+    <string name="show_ime" msgid="2506087537466597099">"물리적 키보드가 활성 상태인 경우 화면에 켜 둠"</string>
+    <string name="hardware" msgid="194658061510127999">"가상 키보드 표시"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"키보드 레이아웃 선택"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"터치하여 키보드 레이아웃을 선택합니다."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"에서 새 사용자를 추가하려고 하지만 사용자 한도에 도달했습니다."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"에서 새 사용자를 추가하려고 하지만 계정 "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"이(가) 이미 기기에 있습니다. 계속할까요?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"에서 계정 "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"에 새 사용자를 추가하려고 합니다. 계속할까요?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"언어 환경설정"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"지역 환경설정"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"언어 이름 입력"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"추천"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"모든 언어"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"검색"</string>
 </resources>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 58402e9..f9dcce5 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ката тууралуу билдирүү"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Ката тууралуу билдирүү түзүү"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Бул сиздин түзмөгүңүздүн учурдагы абалын эмейл билдирүүсү катары жөнөтүш максатында маалымат чогултат. Ката тууралуу билдирүү түзүлүп башталып, жөнөтүлгөнгө чейин бир аз убакыт керек болот; сураныч, бир аз күтө туруңуз."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивдүү кабар"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Ката жөнүндө кабардын абалын жана көйгөй тууралуу кошумча маалыматты көрсөтүү үчүн ушул функцияны колдонууну сунуштайбыз. Ката жөнүндө кабар жөнөтүлүп жатканда көп убакыт талап кылынбашы үчүн негизги бөлүмдөр гана көрүнөт."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Толук кабар берүү"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Мүчүлүштүк тууралуу кабарлоо үчүн <xliff:g id="NUMBER_1">%d</xliff:g> секундда скриншот алынат.</item>
+      <item quantity="one">Мүчүлүштүк тууралуу кабарлоо үчүн <xliff:g id="NUMBER_0">%d</xliff:g> секундда скриншот алынат.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Үнсүз режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Добушу ӨЧҮК"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Добушу КҮЙҮК"</string>
@@ -1043,15 +1043,15 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB мүчүлүштүктөрдү оңдоо туташтырылган"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB мүчүлүштүктөрдү жоюу мүмкүнчүлүгүн өчүрүү үчүн тийип коюңуз."</string>
     <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Администратор менен мүчүлүштүктөр тууралуу кабар бөлүшүлсүнбү?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT администраторуңуз бузулууларды аныктап оңдоого жардам берүү үчүн мүчүлүштүктөр тууралу кабар берүүнү суранды"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT администраторуңуз мүчүлүштүктөр тууралуу маалыматты сурап жатат. Бул маалыматтын жардамы менен бузулган жерлерди аныктап, оңдоп берет."</string>
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"КАБЫЛ АЛУУ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ЧЕТКЕ КАГУУ"</string>
     <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Мүчүлүштүк тууралуу кабар алынууда…"</string>
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Жокко чыгаруу үчүн тийип коюңуз"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Баскычтопту өзгөртүү"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Баскычтопторду тандаңыз"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Киргизүү ыкмасын көрсөтүү"</string>
-    <string name="hardware" msgid="7517821086888990278">"Аппараттык"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Баскычтоп иштетилгенде экранда көрүнүп турсун"</string>
+    <string name="hardware" msgid="194658061510127999">"Виртуалдык баскычтоп"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Тергичтин жайгашуусун тандоо"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Тергичтин жайгашуусун тандаш үчүн басыңыз."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1528,8 +1528,14 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Калган-каткандар"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Бул эскертмелердин маанилүүлүгүн белгиледиңиз."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Булар сиз үчүн маанилүү адамдар."</string>
-    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучу кошууга аракет кылууда, бирок учурда ага тыюу салынган."</string>
-    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучу кошууга аракет кылууда, бирок колдонуучулар чегине жетип калды."</string>
-    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучу кошууга аракет кылууда, бирок "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" каттоо эсеби мурунтан эле бул түзмөктө бар. Баары бир уланта берсинби?"</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучуну кошууга аракет кылууда, бирок учурда ага тыюу салынган."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучуну кошууга аракет кылууда, бирок колдонуучулардын саны эң жогорку чекке жетип калды."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучуну кошууга аракет кылууда, бирок түзмөктө мындай каттоо эсеби "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" мурунтан эле бар. Баары бир уланта бересизби?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучуну "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" каттоо эсебине кошууга аракет кылууда. Улантылсынбы?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Тил жөндөөлөрү"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Чөлкөмдүк жөндөөлөр"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Тилди киргизиңиз"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Сунушталган"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Бардык тилдер"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Издөө"</string>
 </resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 94897ac..1fe72ac 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ລາຍງານຂໍ້ຜິດພາດ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ໃຊ້ລາຍງານຂໍ້ບົກພ່ອງ"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ນີ້ຈະເປັນການເກັບກຳຂໍ້ມູນກ່ຽວກັບ ສະຖານະປັດຈຸບັນຂອງອຸປະກອນທ່ານ ເພື່ອສົ່ງເປັນຂໍ້ຄວາມທາງອີເມວ. ມັນຈະໃຊ້ເວລາໜ້ອຍນຶ່ງ ໃນການເລີ່ມຕົ້ນການລາຍງານຂໍ້ຜິດພາດ ຈົນກວ່າຈະພ້ອມທີ່ຈະສົ່ງໄດ້, ກະລຸນາລໍຖ້າ."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ລາຍງານແບບໂຕ້ຕອບ"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"ໃຊ້ອັນນີ້ພາຍໃຕ້ສະພາບການສ່ວນໃຫຍ່. ມັນອະນຸຍາດໃຫ້ທ່ານຕິດຕາມຄວາມຄືບໜ້າຂອງລາຍງານ ແລະ ປ້ອນລາຍລະອຽດເພີ່ມເຕີມກ່ຽວກັບບັນຫາ. ມັນອາດຈະຕັດບາງສ່ວນທີ່ບໍ່ຄ່ອຍໄດ້ໃຊ້ທີ່ໃຊ້ເວລາດົນໃນການລາຍງານອອກໄປ."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"ລາຍງານເຕັມ"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">ກຳລັງຈະຖ່າຍພາບໜ້າຈໍສຳລັບການລາຍງານຂໍ້ຜິດພາດໃນ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ.</item>
+      <item quantity="one">ກຳລັງຈະຖ່າຍພາບໜ້າຈໍສຳລັບການລາຍງານຂໍ້ຜິດພາດໃນ <xliff:g id="NUMBER_0">%d</xliff:g> ວິນາທີ.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"ໂໝດປິດສຽງ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ປິດສຽງແລ້ວ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ເປິດສຽງແລ້ວ"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ແຕະເພື່ອຍົກເລີກ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"​ປ່ຽນ​ແປ້ນ​ພິມ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"​ເລືອກ​ແປ້ນ​ພິມ"</string>
-    <string name="show_ime" msgid="9157568568695230830">"​ສະ​ແດງ​ຮູບ​ແບບ​ການ​ປ້ອນ​ຂໍ້​ມູນ"</string>
-    <string name="hardware" msgid="7517821086888990278">"ຮາດແວ"</string>
+    <string name="show_ime" msgid="2506087537466597099">"ເປີດໃຊ້ໃຫ້ມັນຢູ່ໃນໜ້າຈໍໃນຂະນະທີ່ໃຊ້ແປ້ນພິມພາຍນອກຢູ່"</string>
+    <string name="hardware" msgid="194658061510127999">"ສະແດງແປ້ນພິມສະເໝືອນ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ເລືອກຮູບແບບແປ້ນພິມ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ກົດເພື່ອເລືອກຮູບແບບແປ້ນພິມ."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ກຳລັງພະຍາຍາມເພີ່ມຜູ້ໃຊ້ໃໝ່, ແຕ່ໄດ້ຮອດຂີດຈຳກັດຜູ້ໃຊ້ແລ້ວ."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ກຳລັງພະຍາຍາມເພີ່ມຜູ້ໃຊ້ໃໝ່, ແຕ່ບັນຊີ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ມີຢູ່ແລ້ວໃນອຸປະກອນນີ້. ແນວໃດກໍດຳເນີນຕໍ່ບໍ?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ກຳລັງພະຍາຍາມເພີ່ມຜູ້ໃຊ້ໃໝ່ສຳລັບບັນຊີ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". ດຳເນີນຕໍ່ບໍ?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"ການຕັ້ງຄ່າພາສາ"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"ການຕັ້ງຄ່າພາກພື້ນ"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"ພິມຊື່ພາສາ"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"ແນະນຳ"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ທຸກພາ​ສາ​"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"ຄົ້ນຫາ"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 5da0a81..2e78344 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -213,15 +213,17 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Pranešimas apie riktą"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Pranešti apie riktą"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Bus surinkta informacija apie dabartinę įrenginio būseną ir išsiųsta el. pašto pranešimu. Šiek tiek užtruks, kol pranešimas apie riktą bus paruoštas siųsti; būkite kantrūs."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interakt. ataskaita"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Naudokite tai esant daugumai aplinkybių. Galite stebėti ataskaitos eigą ir įvesti daugiau išsamios informacijos apie problemą. Gali būti praleidžiamos kelios nelabai naudingos skiltys, kurių ataskaitų teikimas ilgai trunka."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Išsami ataskaita"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Pranešimo apie riktą ekrano kopija bus užfiksuota po <xliff:g id="NUMBER_1">%d</xliff:g> sekundės.</item>
+      <item quantity="few">Pranešimo apie riktą ekrano kopija bus užfiksuota po <xliff:g id="NUMBER_1">%d</xliff:g> sekundžių.</item>
+      <item quantity="many">Pranešimo apie riktą ekrano kopija bus užfiksuota po <xliff:g id="NUMBER_1">%d</xliff:g> sekundės.</item>
+      <item quantity="other">Pranešimo apie riktą ekrano kopija bus užfiksuota po <xliff:g id="NUMBER_1">%d</xliff:g> sekundžių.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tylus režimas"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Garsas IŠJUNGTAS"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Garsas ĮJUNGTAS"</string>
@@ -1063,8 +1065,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Palieskite, kad atšauktumėte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviatūros keitimas"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pasirinkti klaviatūras"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Rodyti įvesties metodą"</string>
-    <string name="hardware" msgid="7517821086888990278">"Apar. įr."</string>
+    <string name="show_ime" msgid="2506087537466597099">"Palikti ekrane, kol fizinė klaviatūra aktyvi"</string>
+    <string name="hardware" msgid="194658061510127999">"Rodyti virtualiąją klaviatūrą"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pasirinkite klaviatūros išdėstymą"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Palieskite, kad pasirinktumėte klaviatūros išdėstymą."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
@@ -1567,4 +1569,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"„<xliff:g id="APP">%1$s</xliff:g>“"</b>" bando pridėti naują naudotoją, tačiau pasiektas naudotojų skaičiaus apribojimas."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"„<xliff:g id="APP">%1$s</xliff:g>“"</b>" bando pridėti naują naudotoją, tačiau paskyra "<b>"„<xliff:g id="ACCOUNT">%2$s</xliff:g>“"</b>" jau yra šiame įrenginyje. Vis tiek tęsti?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"„<xliff:g id="APP">%1$s</xliff:g>“"</b>" bando pridėti naują paskyros "<b>"„<xliff:g id="ACCOUNT">%2$s</xliff:g>“"</b>" naudotoją. Tęsti?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Kalbos nuostata"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Regiono nuostata"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Įveskite kalbos pav."</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Siūloma"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Visos kalbos"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Paieška"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 86d6600..9da04df 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -212,15 +212,16 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Kļūdu ziņojums"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Kļūdu ziņojuma sagatavošana"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Veicot šo darbību, tiks apkopota informācija par jūsu ierīces pašreizējo stāvokli un nosūtīta e-pasta ziņojuma veidā. Kļūdu ziņojuma pabeigšanai un nosūtīšanai var būt nepieciešams laiks. Lūdzu, esiet pacietīgs."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktīvs pārskats"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Izmantojiet lielākajā daļā gadījumu. Varat izsekot pārskata izveides norisi un ievadīt papildu informāciju par problēmu. Var tikt izlaistas dažas mazāk izmantotas sadaļas, kuru izveidei nepieciešams daudz laika."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Viss pārskats"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="zero">Pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm tiks veikts ekrānuzņēmums kļūdas pārskatam.</item>
+      <item quantity="one">Pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundes tiks veikts ekrānuzņēmums kļūdas pārskatam.</item>
+      <item quantity="other">Pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm tiks veikts ekrānuzņēmums kļūdas pārskatam.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Klusuma režīms"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Skaņa ir IZSLĒGTA."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Skaņa ir IESLĒGTA."</string>
@@ -1056,8 +1057,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Pieskarieties, lai atceltu"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Tastatūras maiņa"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Izvēlēties tastatūru"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Rādīt ievades metodi"</string>
-    <string name="hardware" msgid="7517821086888990278">"Aparatūra"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Paturēt ekrānā, kamēr ir aktīva fiziskā tastatūra"</string>
+    <string name="hardware" msgid="194658061510127999">"Virtuālās tastatūras rādīšana"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Atlasiet tastatūras izkārtojumu"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Pieskarieties, lai atlasītu tastatūras izkārtojumu."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
@@ -1549,4 +1550,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mēģina pievienot jaunu lietotāju, taču ir sasniegts lietotāju skaita ierobežojums."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mēģina pievienot jaunu lietotāju, taču šajā ierīcē jau ir izveidots konts "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vai turpināt?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mēģina pievienot jaunu lietotāju kontam "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vai turpināt?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Valodas preference"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Reģiona preference"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Ierakstiet valodas nosaukumu"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Ieteiktās"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Visas valodas"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Meklēt"</string>
 </resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 6acdb45..14fe940 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Извештај за грешка"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Земи извештај за грешки"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ова ќе собира информации за моменталната состојба на вашиот уред, за да ги испрати како порака по е-пошта. Тоа ќе одземе малку време почнувајќи од извештајот за грешки додека не се подготви за праќање; бидете трпеливи."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивен извештај"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Користете го ова во повеќето ситуации. Ви дозволува да го следите напредокот на извештајот и да внесете повеќе детали во врска со проблемот. Може да испушти некои помалку користени делови за коишто е потребно долго време за да се пријават."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Целосен извештај"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Ќе се направи слика од екранот за извештајот за грешки за <xliff:g id="NUMBER_1">%d</xliff:g> секунда.</item>
+      <item quantity="other">Ќе се направи слика од екранот за извештајот за грешки за <xliff:g id="NUMBER_1">%d</xliff:g> секунди.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Тивок режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звукот е исклучен"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звукот е вклучен"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Допрете за да откажете"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Измени тастатура"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Избери тастатури"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Прикажи влезен метод"</string>
-    <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Прикажувај го на екранот додека е активна физичката тастатура"</string>
+    <string name="hardware" msgid="194658061510127999">"Прикажи виртуелна тастатура"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Избери изглед на тастатура"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Допри за да избереш изглед на тастатура."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1533,4 +1533,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" се обидува да додаде нов корисник, но ограничувањето за корисници е достигнато."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" се обидува да додаде нов корисник, но сметката "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" веќе постои на уредот. Сепак продолжете?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" се обидува да додаде нов корисник за сметката "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Продолжете?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Претпочитувања за јазик"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Претпочитувања за регион"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Внеси име на јазик"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Предложени"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Сите јазици"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Пребарај"</string>
 </resources>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 58fc6e1..ce3c32f 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ബഗ് റിപ്പോർട്ട്"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ബഗ് റിപ്പോർട്ട് എടുക്കുക"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ഒരു ഇമെയിൽ സന്ദേശമായി അയയ്‌ക്കുന്നതിന്, ഇത് നിങ്ങളുടെ നിലവിലെ ഉപകരണ നിലയെക്കുറിച്ചുള്ള വിവരങ്ങൾ ശേഖരിക്കും. ബഗ് റിപ്പോർട്ട് ആരംഭിക്കുന്നതിൽ നിന്ന് ഇത് അയയ്‌ക്കാനായി തയ്യാറാകുന്നതുവരെ അൽപ്പസമയമെടുക്കും; ക്ഷമയോടെ കാത്തിരിക്കുക."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ഇന്റരാക്റ്റീവ് റിപ്പോർട്ട്"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"മിക്ക സാഹചര്യങ്ങളിലും ഇത് ഉപയോഗിക്കുക. റിപ്പോർട്ടിന്റെ പുരോഗതി കാണാനും പ്രശ്നത്തിന്റെ കൂടുതൽ വിശദാംശങ്ങളിലേക്ക് പ്രവേശിക്കാനും ഇത് അനുവദിക്കുന്നു. റിപ്പോർട്ടുചെയ്യാൻ നീണ്ട സമയം എടുക്കുന്ന, നിങ്ങൾ കുറവായി ഉപയോഗിക്കുന്ന ചില വിഭാഗങ്ങളെ ഇത് വിട്ടുകളഞ്ഞേക്കാം."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"പൂർണ്ണ റിപ്പോർട്ട്"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">ബഗ് റിപ്പോർട്ടിനായി <xliff:g id="NUMBER_1">%d</xliff:g> സെക്കൻഡിൽ സ്ക്രീൻഷോട്ട് എടുക്കുന്നു.</item>
+      <item quantity="one">ബഗ് റിപ്പോർട്ടിനായി <xliff:g id="NUMBER_0">%d</xliff:g> സെക്കൻഡിൽ സ്ക്രീൻഷോട്ട് എടുക്കുന്നു.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"നിശബ്‌ദ മോഡ്"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ശബ്‌ദം ഓഫാണ്"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ശബ്‌ദം ഓണാണ്"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"റദ്ദാക്കുന്നതിന് സ്പർശിക്കുക"</string>
     <string name="select_input_method" msgid="8547250819326693584">"കീബോഡ് മാറ്റുക"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"കീബോർഡുകൾ തിരഞ്ഞെടുക്കുക"</string>
-    <string name="show_ime" msgid="9157568568695230830">"ടൈപ്പുചെയ്യൽ രീതി കാണിക്കുക"</string>
-    <string name="hardware" msgid="7517821086888990278">"ഹാർഡ്‌വെയർ"</string>
+    <string name="show_ime" msgid="2506087537466597099">"ഭൗതിക കീബോർഡ് സജീവമായിരിക്കുമ്പോൾ സ്ക്രീനിൽ നിലനിർത്തുക"</string>
+    <string name="hardware" msgid="194658061510127999">"വെർച്വൽ കീബോർഡ് കാണിക്കുക"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"കീബോർഡ് ലേഔട്ട് തിരഞ്ഞെടുക്കുക"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ഒരു കീബോർഡ് ലേഔട്ട് തിരഞ്ഞെടുക്കാൻ സ്‌പർശിക്കുക."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കാൻ "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ശ്രമിക്കുന്നു, എന്നാൽ ഉപയോക്തൃ പരിധി എത്തിക്കഴിഞ്ഞിരിക്കുന്നു."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കാൻ "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ശ്രമിക്കുന്നു, എന്നാൽ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" എന്ന അക്കൗണ്ട് ഇതിനകം തന്നെ ഈ ഉപകരണത്തിൽ നിലവിലുണ്ട്. എന്തായാലും തുടരണോ?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" എന്ന അക്കൗണ്ടിനായി പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കാൻ "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ശ്രമിക്കുന്നു. തുടരണോ?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"ഭാഷാ മുൻഗണന"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"മേഖലാ മുൻഗണന"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"ഭാഷയുടെ പേര് ടൈപ്പുചെയ്യുക"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"നിര്‍‌ദ്ദേശിച്ചത്"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"എല്ലാ ഭാഷകളും"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"തിരയുക"</string>
 </resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index b59863b..08233f8 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Алдаа мэдээллэх"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Согог репорт авах"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Энэ таны төхөөрөмжийн одоогийн статусын талаарх мэдээллийг цуглуулах ба имэйл мессеж болгон илгээнэ. Алдааны мэдэгдлээс эхэлж илгээхэд бэлэн болоход хэсэг хугацаа зарцуулагдана тэвчээртэй байна уу."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактив тайлан"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Ихэнх тохиолдолд үүнийг хэрэглэнэ үү. Энэ нь танд тайлангийн явцыг хянах болон асуудлын талаар дэлгэрэнгүйг мэдэх боломж олгоно. Таны бага ашигладаг, тайлагнахад хугацаа их шаарддаг зарим хэсгийг алгана."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Бүрэн тайлан"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Алдааны тайлангийн дэлгэцийн зургийг <xliff:g id="NUMBER_1">%d</xliff:g> секундад авна.</item>
+      <item quantity="one">Алдааны тайлангийн дэлгэцийн зургийг <xliff:g id="NUMBER_0">%d</xliff:g> секундад авна.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Чимээгүй горим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Дуу хаагдсан"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Дуу асав"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Цуцлахын тулд хүрэх"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Гарыг өөрчлөх"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Гар сонгох"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Оруулах аргыг харуулах"</string>
-    <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Бодит гар идэвхтэй үед үүнийг дэлгэцэнд харуулна уу"</string>
+    <string name="hardware" msgid="194658061510127999">"Хийсвэр гарыг харуулах"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Гарын схемийг сонгох"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Гарын схемийг сонгох бол хүрнэ үү."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1527,6 +1527,12 @@
     <string name="importance_from_person" msgid="9160133597262938296">"Оролцсон хүмүүсээс шалтгаалан энэ нь өндөр ач холбогдолтой."</string>
     <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" шинэ хэрэглэгч нэмэхээр оролдож байгаа боловч одоогоор боломжгүй байна."</string>
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" шинэ хэрэглэгч нэмэхээр оролдож байгаа ч хэрэглэгчийн тооны хязгаарт хүрсэн байна."</string>
-    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" шинэ хэрэглэгч нэмэх гэсэн боловч "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" бүртгэл нь энэ төхөөрөмжид аль хэдийн байна. Гэсэн хэдий ч үргэлжлүүлэх үү?"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" шинэ хэрэглэгч нэмэх гэсэн боловч "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" бүртгэл нь энэ төхөөрөмжид аль хэдийн бүртгэгдсэн байна. Үргэлжлүүлэх үү?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" нь "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" бүртгэлд шинэ хэрэглэгч нэмэх гэж байна. Үргэлжлүүлэх үү?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Хэлний тохиргоо"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Бүс нутгийн тохиргоо"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Улсын хэлийг бичнэ үү"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Санал болгосон"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Бүх хэл"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Хайх"</string>
 </resources>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index bf52c38..30edff7 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"दोष अहवाल"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"दोष अहवाल घ्या"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ई-मेल संदेश म्हणून पाठविण्यासाठी, हे आपल्या वर्तमान डिव्हाइस स्थितीविषयी माहिती संकलित करेल. दोष अहवाल प्रारंभ करण्यापासून तो पाठविण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"परस्परसंवादी अहवाल"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"बहुतांश प्रसंगांमध्‍ये याचा वापर करा. ते आपल्‍याला अहवालाच्या प्रगतीचा मागोवा घेण्‍याची आणि समस्येविषयी अधिक तपशील प्रविष्‍ट करण्‍याची अनुमती देतात. ते अहवाल देण्‍यासाठी बराच वेळ घेणार्‍या कमी वापरलेल्या विभागांना कदाचित वगळेल."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"संपूर्ण अहवाल"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">दोष अहवालासाठी <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदामध्‍ये स्क्रीनशॉट घेत आहे.</item>
+      <item quantity="other">दोष अहवालासाठी <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्‍ये स्क्रीनशॉट घेत आहे.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"मूक मोड"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ध्वनी बंद आहे"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ध्वनी चालू आहे"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"रद्द करण्यासाठी स्पर्श करा"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदला"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड निवडा"</string>
-    <string name="show_ime" msgid="9157568568695230830">"इनपुट पद्धत दर्शवा"</string>
-    <string name="hardware" msgid="7517821086888990278">"हार्डवेअर"</string>
+    <string name="show_ime" msgid="2506087537466597099">"भौतिक कीबोर्ड सक्रिय असताना त्यास स्क्रीनवर ठेवा"</string>
+    <string name="hardware" msgid="194658061510127999">"व्हर्च्युअल कीबोर्ड दर्शवा"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"कीबोर्ड लेआउट निवडा"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"कीबोर्ड लेआउट निवडण्यासाठी स्पर्श करा."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" नवीन वापरकर्ता जोडण्यासाठी प्रयत्न करीत आहे परंतु वापरकर्ता मर्यादा गाठली गेली आहे."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" नवीन वापरकर्ता जोडण्‍याचा प्रयत्न करीत आहे परंतु या डिव्‍हाइसवर "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" खाते आधीपासून अस्तित्वात आहे. तरीही पुढे सुरु ठेवायचे?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" खात्यासाठी "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" नवीन वापरकर्ता जोडण्याचा प्रयत्न करीत आहे. पुढे सुरु ठेवायचे?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"भाषा प्राधान्य"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"प्रदेश प्राधान्य"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"भाषा नाव टाइप करा"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"सूचित केलेले"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"सर्व भाषा"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"शोध"</string>
 </resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index eaa3dcf..3f1bb14 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Laporan pepijat"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan pepijat"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpul maklumat tentang keadaan peranti semasa anda untuk dihantarkan sebagai mesej e-mel. Harap bersabar, mungkin perlu sedikit masa untuk memulakan laporan sehingga siap untuk dihantar."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Laporan interaktif"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Gunakan laporan ini dalam kebanyakan keadaan. Anda boleh menjejak kemajuan dan memasukkan butiran lanjut tentang masalah tersebut. Laporan ini mungkin meninggalkan beberapa bahagian yang kurang digunakan, yang mengambil masa lama untuk dilaporkan."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Laporan penuh"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Mengambil tangkapan skrin untuk laporan pepijat dalam masa <xliff:g id="NUMBER_1">%d</xliff:g> saat.</item>
+      <item quantity="one">Mengambil tangkapan skrin untuk laporan pepijat dalam masa <xliff:g id="NUMBER_0">%d</xliff:g> saat.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mod senyap"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Bunyi DIMATIKAN"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Bunyi DIHIDUPKAN"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Sentuh untuk membatalkan"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Tukar papan kekunci"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pilih papan kekunci"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Tunjukkan kaedah input"</string>
-    <string name="hardware" msgid="7517821086888990278">"Perkakasan"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Pastikannya pada skrin, semasa papan kekunci fizikal aktif"</string>
+    <string name="hardware" msgid="194658061510127999">"Tunjukkan papan kekunci maya"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pilih susun atur papan kekunci"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Sentuh untuk memilih susun atur papan kekunci."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1529,6 +1529,12 @@
     <string name="importance_from_person" msgid="9160133597262938296">"Mesej ini penting disebabkan orang yang terlibat."</string>
     <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" cuba menambahkan pengguna baharu tetapi dilarang pada masa ini."</string>
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" cuba menambahkan pengguna baharu tetapi had pengguna telah dicapai."</string>
-    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" cuba menambahkan pengguna baharu tetapi akaun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" telah wujud pada peranti ini. Teruskan juga?"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" cuba menambahkan pengguna baharu tetapi akaun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" sudah wujud pada peranti ini. Teruskan juga?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" cuba menambahkan pengguna baharu untuk akaun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Teruskan?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Pilihan bahasa"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Pilihan wilayah"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Taipkan nama bahasa"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Dicadangkan"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Semua bahasa"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Cari"</string>
 </resources>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index c980731..17c1eda 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်း"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းအား ယူရန်"</string>
     <string name="bugreport_message" msgid="398447048750350456">"သင့်ရဲ့ လက်ရှိ စက်အခြေအနေ အချက်အလက်များကို အီးမေးလ် အနေဖြင့် ပေးပို့ရန် စုဆောင်းပါမည်။ အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းမှ ပေးပို့ရန် အသင့်ဖြစ်သည်အထိ အချိန် အနည်းငယ်ကြာမြင့်မှာ ဖြစ်သဖြင့် သည်းခံပြီး စောင့်ပါရန်"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"လက်ငင်းတုံ့ပြန်နိုင်သည့် အစီရင်ခံချက်"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"အများအားဖြင့် ၎င်းကိုအသုံးပြုပါ။ ၎င်းသည် အစီရင်ခံချက်ကို ခြေရာခံခွင့်ပေးပြီး ပြဿနာအကြောင်း အသေးစိတ်များကို ထည့်ခွင့်ပြုပါသည်။ အစီရင်ခံရန်ကြာသည့် သိပ်မသုံးသော ကဏ္ဍများကို ချန်ထားခဲ့နိုင်ပါသည်။"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"အစီရင်ခံချက်အပြည့်"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> စက္ကန့်အတွင်း ချွတ်ယွင်းချက် အစီရင်ခံရန်အတွက် မျက်နှာပြင်ဓာတ်ပုံ ရိုက်ပါမည်။</item>
+      <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> စက္ကန့်အတွင်း ချွတ်ယွင်းချက် အစီရင်ခံရန်အတွက် မျက်နှာပြင်ဓာတ်ပုံ ရိုက်ပါမည်။</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"အသံတိတ်စနစ်"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"အသံပိတ်ထားသည်"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"အသံဖွင့်ထားသည်"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ဖျက်သိမ်းရန် တို့ပါ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ကီးဘုတ် ပြောင်းလဲရန်"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ကီးဘုတ်များကို ရွေးရန်"</string>
-    <string name="show_ime" msgid="9157568568695230830">"ရိုက်သွင်းမှု နည်းလမ်းကို ပြရန်"</string>
-    <string name="hardware" msgid="7517821086888990278">"ဟာ့ဒ်ဝဲ"</string>
+    <string name="show_ime" msgid="2506087537466597099">"စက်၏ကီးဘုတ်ကိုအသုံးပြုနေစဉ် ၎င်းကိုမျက်နှာပြင်ပေါ်တွင် ထားပါ"</string>
+    <string name="hardware" msgid="194658061510127999">"ကီးဘုတ်အတုပြရန်"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"လက်ကွက် အပြင်အဆင်ရွေးရန်"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"လက်ကွက် အပြင်အဆင်ရွေးရန် တို့ထိပါ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"က အသုံးပြုသူ အသစ်ကို ထည့်ရန် ကြိုးစားနေပါသည်၊ သို့သော် အသုံးပြုသူ ကန့်သတ်ချက် ပြည့်မီသွားပါပြီ။"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"က အသုံးပြုသူ အသစ်ကို ထည့်ရန် ကြိုးစားနေပါသည်၊ သို့သော် အကောင့် "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"မှာ ဤကိရိယာထဲတွင် ရှိနှင့်နေပါပြီ။ မည်သို့ပင်ဖြစ်စေ ဆက်လက်လုပ်ဆောင်ရမလား။"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"က အကောင့် "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"အတွက် အသုံးပြုသူ အသစ်ကို ထည့်ရန် ကြိုးစားနေပါသည်။ ဆက်လက်လုပ်ဆောင်ရမလား။"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"ဘာသာစကားရွေးချယ်မှု"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"ဒေသရွေးချယ်မှု"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"ဘာသာစကားအမည် ထည့်ပါ"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"အကြံပြုထားသော"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ဘာသာစကားများအားလုံး"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"ရှာဖွေရန်"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 9efa863..2385ad7 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Feilrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Utfør feilrapport"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Informasjon om tilstanden til enheten din samles inn og sendes som en e-post. Det tar litt tid fra du starter feilrapporten til e-posten er klar, så vær tålmodig."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv rapport"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Bruk dette alternativet i de fleste tilfeller. Da kan du spore fremgangen for rapporten samt skrive inn flere detaljer om problemet. Noen deler som tar lang tid å behandle, blir kanskje utelatt."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Fullstendig rapport"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Tar skjermdump for feilrapporten om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder.</item>
+      <item quantity="one">Tar skjermdump for feilrapporten om <xliff:g id="NUMBER_0">%d</xliff:g> sekund.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Stillemodus"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Lyden er av"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Lyden er på"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Trykk for å avbryte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Endre tastatur"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Velg tastatur"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Vis inndatametode"</string>
-    <string name="hardware" msgid="7517821086888990278">"Maskinvare"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Ha den på skjermen mens det fysiske tastaturet er aktivt"</string>
+    <string name="hardware" msgid="194658061510127999">"Vis det virtuelle tastaturet"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Velg tastaturoppsett"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Trykk for å velge et tastaturoppsett"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" prøver å legge til en ny bruker, men brukergrensen er nådd."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" prøver å legge til en ny bruker, men kontoen "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" finnes allerede på denne enheten. Vil du fortsette likevel?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" prøver å legge til en ny bruker på kontoen "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vil du fortsette?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Språkinnstilling"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Regionsinnstilling"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Skriv inn språknavn"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Foreslått"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Alle språk"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Søk"</string>
 </resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index f7b96d9..3e0cb29 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -146,7 +146,7 @@
     <string name="httpErrorLookup" msgid="4711687456111963163">"URL भेटाउन सकेन।"</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"साइटको आधिकारिकता योजना समर्थित छैन।"</string>
     <string name="httpErrorAuth" msgid="1435065629438044534">"प्रमाणीकरण गर्न सकेन।"</string>
-    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"प्रोक्सी सर्भरको माध्यमद्वारा प्रमाणिकरण असफल भएको छ।"</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"प्रोक्सी सर्भरको माध्यमद्वारा प्रमाणीकरण असफल भएको छ।"</string>
     <string name="httpErrorConnect" msgid="8714273236364640549">"सर्भरसँग जोड्न सकेन।"</string>
     <string name="httpErrorIO" msgid="2340558197489302188">"सर्भरसँग संचार गर्न सकेन। फेरि पछि कोसिस गर्नुहोस्।"</string>
     <string name="httpErrorTimeout" msgid="4743403703762883954">"सर्भर संगको सम्पर्क प्रक्रिया समय सकियो।"</string>
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"बग रिपोर्ट"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"बग रिपोर्ट लिनुहोस्"</string>
     <string name="bugreport_message" msgid="398447048750350456">"एउटा इमेल सन्देशको रूपमा पठाउनलाई यसले तपाईँको हालैको उपकरणको अवस्थाको बारेमा सूचना जम्मा गर्ने छ। बग रिपोर्ट सुरु गरेदेखि पठाउन तयार नभएसम्म यसले केही समय लिन्छ; कृपया धैर्य गर्नुहोस्।"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"पारस्परिक रिपोर्ट"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"यसलाई धेरै परिस्थिति भन्दा मुनि प्रयोग गर्नुहोस्। यसले तपाईंलाई रिपोर्टको प्रगति ट्र्याक गर्न र समस्या सम्बन्धी थप विवरणहरू प्रविष्ट गर्न अनुमति दिन्छ। यसले रिपोर्ट गर्न धेरै नै समय लिने केही कम प्रयोग भएका खण्डहरू मेटाउन सक्छ।"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"पूर्ण रिपोर्ट"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other"> बग रिपोर्टको लागि <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा स्क्रिनशट लिँदै।</item>
+      <item quantity="one"> बग रिपोर्टको लागि <xliff:g id="NUMBER_0">%d</xliff:g> सेकेन्डमा स्क्रिनशट लिँदै।</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"मौन मोड"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"आवाज बन्द छ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ध्वनि खुल्ला छ"</string>
@@ -1047,7 +1047,7 @@
     <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_title" msgid="3116061729914615290">"प्रशासकसँग बग रिपोर्ट साझेदारी गर्ने हो?"</string>
     <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"तपाईंको IT व्यवस्थापकले समस्या निवारणमा मद्दत गर्न बग रिपोर्ट अनुरोध गर्नुभयो"</string>
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"स्वीकार गर्नुहोस्"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"अस्वीकार गर्नुहोस्"</string>
@@ -1055,8 +1055,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"रद्द गर्न छुनुहोस्"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कुञ्जीपाटी परिवर्तन गर्नुहोस्"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड छान्नुहोस्"</string>
-    <string name="show_ime" msgid="9157568568695230830">"आगत विधि देखाउनुहोस्"</string>
-    <string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
+    <string name="show_ime" msgid="2506087537466597099">"भौतिक किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राख्नुहोस्"</string>
+    <string name="hardware" msgid="194658061510127999">"भर्चुअल किबोर्ड देखाउनुहोस्"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"किबोर्ड रूपरेखा चयन गर्नुहोस्"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"किबोर्ड रूपरेखा चयन गर्न टच गर्नुहोस्।"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1533,8 +1533,14 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"विविध"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"तपाईंले यी सूचनाहरूको महत्त्व सेट गर्नुहुन्छ।"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"यसमा सङ्लग्न भएका मानिसहरूको कारणले गर्दा यो महत्वपूर्ण छ।"</string>
-    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ले नयाँ प्रयोगकर्ता थप्ने प्रयास गरिरहेको छ तर हाललाई निषेध छ।"</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ले नयाँ प्रयोगकर्ता थप्ने प्रयास गरिरहेको छ तर हाललाई निषेधित छ।"</string>
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ले नयाँ प्रयोगकर्ता थप्ने प्रयास गरिरहेको छ तर प्रयोगकर्ताको सीमा पुगेको छ।"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ले नयाँ प्रयोगकर्ता थप्ने प्रयास गरिरहेको छ तर यो यन्त्रमा खाता "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" पहिले नै अवस्थित छ। जे भए पनि अगाडि बढ्ने हो?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ले खाता "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" मा नयाँ प्रयोगकर्ता थप्ने प्रयास गरिरहेको छ। अगाडि बढ्ने हो?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"भाषाको प्राथमिकता"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"क्षेत्रको प्राथमिकता"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"भाषाको नाम टाइप गर्नुहोस्"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"सुझाव दिइयो"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"सम्पूर्ण भाषाहरू"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"खोज"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index cd70afa..d0a333b 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Foutenrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Foutenrapport genereren"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Hiermee worden gegevens over de huidige status van je apparaat verzameld en als e-mail verzonden. Wanneer u een foutenrapport start, duurt het even voordat het kan worden verzonden. Even geduld alstublieft."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactief rapport"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Gebruik deze optie in de meeste situaties. Hiermee kun je de voortgang van het rapport bijhouden en meer gegevens over het probleem opgeven. Mogelijk worden bepaalde minder vaak gebruikte gedeelten weggelaten (waarvoor het lang zou duren om een rapport te genereren)."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Volledig rapport"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Er wordt over <xliff:g id="NUMBER_1">%d</xliff:g> seconden een screenshot gemaakt voor het bugrapport.</item>
+      <item quantity="one">Er wordt over <xliff:g id="NUMBER_0">%d</xliff:g> seconde een screenshot gemaakt voor het bugrapport.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Stille modus"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Geluid is UIT"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Geluid is AAN"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tik om te annuleren"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Toetsenbord wijzigen"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Toetsenborden kiezen"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Invoermethode weergeven"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Dit op het scherm weergeven terwijl het fysieke toetsenbord actief is"</string>
+    <string name="hardware" msgid="194658061510127999">"Virtueel toetsenbord tonen"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Toetsenbordindeling selecteren"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Tik om een ​​toetsenbordindeling te selecteren."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeert een nieuwe gebruiker toe te voegen, maar de gebruikerslimiet is al bereikt."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeert een nieuwe gebruiker toe te voegen, maar het account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" bestaat al op dit apparaat. Toch doorgaan?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" probeert een nieuwe gebruiker toe te voegen voor het account "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Doorgaan?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Taalvoorkeur"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Regiovoorkeur"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Typ een taalnaam"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Voorgesteld"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Alle talen"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Zoeken"</string>
 </resources>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 7c9f1b4..7e762b0 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ਬਗ ਰਿਪੋਰਟ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ਬਗ ਰਿਪੋਰਟ ਲਓ"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ਇਹ ਇੱਕ ਈ-ਮੇਲ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ, ਤੁਹਾਡੀ ਵਰਤਮਾਨ ਡਿਵਾਈਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਤਰ ਕਰੇਗਾ। ਬਗ ਰਿਪੋਰਟ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਥੋੜ੍ਹਾ ਸਮਾਂ ਲੱਗੇਗਾ ਜਦੋਂ ਤੱਕ ਇਹ ਭੇਜੇ ਜਾਣ ਲਈ ਤਿਆਰ ਨਾ ਹੋਵੇ, ਕਿਰਪਾ ਕਰਕੇ ਧੀਰਜ ਰੱਖੋ।"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ਅੰਤਰਕਿਰਿਆਤਮਕ ਰਿਪੋਰਟ"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"ਜ਼ਿਆਦਾਤਰ ਹਾਲਾਤਾਂ ਵਿੱਚ ਇਸ ਦੀ ਵਰਤੋਂ ਕਰੋ। ਇਹ ਤੁਹਾਨੂੰ ਰਿਪੋਰਟ ਦੀ ਪ੍ਰਗਤੀ ਨੂੰ ਟਰੈਕ ਕਰਨ ਦਿੰਦਾ ਹੈ ਅਤੇ ਸਮੱਸਿਆ ਬਾਰੇ ਹੋਰ ਵੇਰਵੇ ਦਾਖਲ ਕਰਨ ਦਿੰਦਾ ਹੈ। ਇਹ ਉਹਨਾਂ ਘੱਟ-ਵਰਤੇ ਗਏ ਕੁਝ ਭਾਗਾਂ ਨੂੰ ਨਜ਼ਰ-ਅੰਦਾਜ਼ ਕਰ ਸਕਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਦੀ ਰਿਪੋਰਟ ਕਰਨ ਵਿੱਚ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ।"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"ਪੂਰੀ ਰਿਪੋਰਟ"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">ਬੱਗ ਰਿਪੋਰਟ ਲਈ <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟ ਵਿੱਚ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ।</item>
+      <item quantity="other">ਬੱਗ ਰਿਪੋਰਟ ਲਈ <xliff:g id="NUMBER_1">%d</xliff:g> ਸਕਿੰਟ ਵਿੱਚ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਿਆ ਜਾ ਰਿਹਾ ਹੈ।</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"ਸਾਈਲੈਂਟ ਮੋਡ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ਅਵਾਜ਼ ਬੰਦ ਹੈ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ਅਵਾਜ਼ ਚਾਲੂ ਹੈ"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ਰੱਦ ਕਰਨ ਲਈ ਸਪਰਸ਼ ਕਰੋ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ਕੀਬੋਰਡ ਬਦਲੋ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ਕੀਬੋਰਡਸ ਚੁਣੋ"</string>
-    <string name="show_ime" msgid="9157568568695230830">"ਇਨਪੁਟ ਵਿਧੀ ਦਿਖਾਓ"</string>
-    <string name="hardware" msgid="7517821086888990278">"ਹਾਰਡਵੇਅਰ"</string>
+    <string name="show_ime" msgid="2506087537466597099">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਸਰਗਰਮ ਹੋਣ ਦੌਰਾਨ ਇਸ ਨੂੰ ਸਕ੍ਰੀਨ \'ਤੇ ਬਣਾਈ ਰੱਖੋ"</string>
+    <string name="hardware" msgid="194658061510127999">"ਵਰਚੁਅਲ ਕੀ-ਬੋਰਡ ਵਿਖਾਓ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ਕੀਬੋਰਡ ਲੇਆਊਟ ਚੁਣੋ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ਇੱਕ ਕੀਬੋਰਡ ਲੇਆਊਟ ਚੁਣਨ ਲਈ ਛੋਹਵੋ।"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ਇੱਕ ਨਵੇਂ ਵਰਤੋਂਕਾਰ ਨੂੰ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਿਹਾ ਹੈ, ਪਰ ਵਰਤੋਂਕਾਰ ਮਿਆਦ ਪੂਰੀ ਹੋ ਚੁੱਕੀ ਹੈ।"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ਇੱਕ ਨਵੇਂ ਵਰਤੋਂਕਾਰ ਨੂੰ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਿਹਾ ਹੈ, ਪਰ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ਖਾਤਾ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਮੌਜੂਦ ਹੈ। ਕੀ ਫਿਰ ਵੀ ਅੱਗੇ ਵੱਧਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ਖਾਤੇ ਵਿੱਚ ਇੱਕ ਨਵੇਂ ਵਰਤੋਂਕਾਰ ਨੂੰ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਿਹਾ ਹੈ। ਕੀ ਅੱਗੇ ਵੱਧਣਾ ਹੈ?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"ਭਾਸ਼ਾ ਤਰਜੀਹ"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"ਖੇਤਰ ਤਰਜੀਹ"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"ਭਾਸ਼ਾ ਨਾਮ ਟਾਈਪ ਕਰੋ"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"ਸੁਝਾਈਆਂ ਗਈਆਂ"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ਸਾਰੀਆਂ ਭਾਸ਼ਾਵਾਂ"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"ਖੋਜ"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 1e5bc5f..8f475d5 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -213,15 +213,17 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Zgłoszenie błędu"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Zgłoś błąd"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Informacje o bieżącym stanie urządzenia zostaną zebrane i wysłane e-mailem. Przygotowanie zgłoszenia błędu do wysłania chwilę potrwa, więc zachowaj cierpliwość."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Raport interaktywny"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Używaj tej opcji w większości przypadków. Umożliwia śledzenie postępów raportu i podanie dodatkowych szczegółów problemu. Raport może pomijać niektóre rzadko używane sekcje, których utworzenie zajmuje dużo czasu."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Pełny raport"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="few">Zrzut ekranu do raportu o błędzie zostanie zrobiony za <xliff:g id="NUMBER_1">%d</xliff:g> sekundy.</item>
+      <item quantity="many">Zrzut ekranu do raportu o błędzie zostanie zrobiony za <xliff:g id="NUMBER_1">%d</xliff:g> sekund.</item>
+      <item quantity="other">Zrzut ekranu do raportu o błędzie zostanie zrobiony za <xliff:g id="NUMBER_1">%d</xliff:g> sekundy.</item>
+      <item quantity="one">Zrzut ekranu do raportu o błędzie zostanie zrobiony za <xliff:g id="NUMBER_0">%d</xliff:g> sekundę.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tryb cichy"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Dźwięk jest wyłączony"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Dźwięk jest włączony"</string>
@@ -1063,8 +1065,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Kliknij, by anulować"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Zmień klawiaturę"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Wybierz klawiatury"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Pokaż metodę wprowadzania"</string>
-    <string name="hardware" msgid="7517821086888990278">"Sprzęt"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Pozostaw na ekranie, gdy aktywna jest klawiatura fizyczna"</string>
+    <string name="hardware" msgid="194658061510127999">"Pokaż klawiaturę wirtualną"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Wybierz układ klawiatury"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Kliknij, by wybrać układ klawiatury."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
@@ -1567,4 +1569,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Aplikacja "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" próbuje dodać nowego użytkownika, ale osiągnięto już limit użytkowników."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"Aplikacja "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" próbuje dodać nowego użytkownika, ale na tym urządzeniu istnieje już konto "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Kontynuować mimo to?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392">"Aplikacja "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" próbuje dodać nowego użytkownika do konta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Kontynuować?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Ustawienie języka"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Ustawienie regionu"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Wpisz nazwę języka"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Sugerowane"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Wszystkie języki"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Szukaj"</string>
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 1d0d9e5..60d4860 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de bugs"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Obter relatório de bugs"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Isto coletará informações sobre o estado atual do dispositivo para enviá-las em uma mensagem de e-mail. Após iniciar o relatório de bugs, será necessário aguardar algum tempo até que esteja pronto para ser enviado."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Relatório interativo"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Use este recurso na maioria das circunstâncias. Ele permite que você acompanhe o progresso do relatório e informe mais detalhes sobre o problema. É possível que ele omita algumas seções menos utilizadas que levam muito tempo na emissão dos relatórios."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Relatório completo"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Capturas de tela para o relatório do bug serão feitas em <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
+      <item quantity="other">Capturas de tela para o relatório do bug serão feitas em <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Som DESATIVADO"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O som está ATIVADO"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toque para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Manter na tela enquanto o teclado físico estiver ativo"</string>
+    <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecione o layout de teclado"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toque para selecionar um layout de teclado."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas o limite de usuários foi atingido."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas a conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" já existe neste dispositivo. Continuar mesmo assim?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário à conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuar?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferência de idioma"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Digitar nome do idioma"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Sugeridos"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Todos os idiomas"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Pesquisa"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 453179a..e58e693 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de erros"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Criar relatório de erros"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Será recolhida informação sobre o estado atual do seu dispositivo a enviar através de uma mensagem de email. Demorará algum tempo até que o relatório de erro esteja pronto para ser enviado. Aguarde um pouco."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Relatório interativo"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Utilize esta opção na maioria das circunstâncias. Permite monitorizar o progresso do relatório e introduzir mais detalhes acerca do problema. Pode omitir algumas secções menos utilizadas que demoram muito tempo a comunicar."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Relatório completo"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">A tirar uma captura de ecrã do relatório de erro dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
+      <item quantity="one">A tirar uma captura de ecrã do relatório de erro dentro de <xliff:g id="NUMBER_0">%d</xliff:g> segundo.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Som desativado"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O som está ativado"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toque para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Manter no ecrã enquanto o teclado físico estiver ativo"</string>
+    <string name="hardware" msgid="194658061510127999">"Mostrar o teclado virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecionar esquema de teclado"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toque para selecionar um esquema de teclado."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1527,8 +1527,14 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diversos"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Definiu a importância destas notificações."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"É importante devido às pessoas envolvidas."</string>
-    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está a tentar adicionar um novo utilizador, mas está atualmente proibido."</string>
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está a tentar adicionar um novo utilizador, mas está atualmente proibido(a)."</string>
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está a tentar adicionar um novo utilizador, mas foi atingido o limite de utilizadores."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está a tentar adicionar um novo utilizador, mas a conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" já existe neste dispositivo. Pretende continuar mesmo assim?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está a tentar adicionar um novo utilizador à conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Pretende continuar?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferência de idioma"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Intr. nome do idioma"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Sugeridos"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Todos os idiomas"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Pesquisa"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1d0d9e5..60d4860 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de bugs"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Obter relatório de bugs"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Isto coletará informações sobre o estado atual do dispositivo para enviá-las em uma mensagem de e-mail. Após iniciar o relatório de bugs, será necessário aguardar algum tempo até que esteja pronto para ser enviado."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Relatório interativo"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Use este recurso na maioria das circunstâncias. Ele permite que você acompanhe o progresso do relatório e informe mais detalhes sobre o problema. É possível que ele omita algumas seções menos utilizadas que levam muito tempo na emissão dos relatórios."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Relatório completo"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Capturas de tela para o relatório do bug serão feitas em <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
+      <item quantity="other">Capturas de tela para o relatório do bug serão feitas em <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Som DESATIVADO"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O som está ATIVADO"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toque para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Manter na tela enquanto o teclado físico estiver ativo"</string>
+    <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecione o layout de teclado"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toque para selecionar um layout de teclado."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas o limite de usuários foi atingido."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas a conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" já existe neste dispositivo. Continuar mesmo assim?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário à conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuar?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferência de idioma"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Digitar nome do idioma"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Sugeridos"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Todos os idiomas"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Pesquisa"</string>
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 3602d91..4db1209 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -212,15 +212,16 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Raport despre erori"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Executați un raport despre erori"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Acest raport va colecta informații despre starea actuală a dispozitivului, pentru a le trimite într-un e-mail. Aveți răbdare după pornirea raportului despre erori până când va fi gata de trimis."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Raport interactiv"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Folosiți această opțiune în majoritatea situațiilor. Astfel, puteți să urmăriți progresul raportului și să introduceți mai multe detalii în privința problemei. Pot fi omise unele secțiuni mai puțin folosite pentru care raportarea durează prea mult."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Raport complet"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="few">Peste <xliff:g id="NUMBER_1">%d</xliff:g> secunde se va realiza o captură de ecran pentru raportul de eroare.</item>
+      <item quantity="other">Peste <xliff:g id="NUMBER_1">%d</xliff:g> de secunde se va realiza o captură de ecran pentru raportul de eroare.</item>
+      <item quantity="one">Peste <xliff:g id="NUMBER_0">%d</xliff:g> secundă se va realiza o captură de ecran pentru raportul de eroare.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mod Silențios"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sunetul este DEZACTIVAT"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sunetul este ACTIVAT"</string>
@@ -1056,8 +1057,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Atingeți pentru a anula"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Schimbați tastatura"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Alegeți tastaturi"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Afișați metoda de introducere a textului"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Se păstrează pe ecran cât timp este activată tastatura fizică"</string>
+    <string name="hardware" msgid="194658061510127999">"Afișați tastatura virtuală"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selectați aspectul tastaturii"</string>
     <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>
@@ -1549,4 +1550,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" încearcă să adauge un nou utilizator, dar a fost atinsă limita de utilizatori."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" încearcă să adauge un nou utilizator, dar contul "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" există deja pe acest dispozitiv. Continuați oricum?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" încearcă să adauge un nou utilizator pentru contul "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuați?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Limba preferată"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Regiunea preferată"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Scrieți nume limbă"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Sugerate"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Toate limbile"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Căutați"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 2d69607..1185422 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -213,15 +213,17 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Отчет об ошибке"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Отчет об ошибке"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Информация о текущем состоянии вашего устройства будет собрана и отправлена по электронной почте. Подготовка отчета займет некоторое время."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивный отчет"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Рекомендуем пользоваться этой функцией, чтобы отслеживать статус отчета и указывать дополнительные данные о проблеме. Показываются только основные разделы (чтобы отправка отчета об ошибке занимала меньше времени)."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Подробный отчет"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Скриншот будет сделан через <xliff:g id="NUMBER_1">%d</xliff:g> секунду</item>
+      <item quantity="few">Скриншот будет сделан через <xliff:g id="NUMBER_1">%d</xliff:g> секунды</item>
+      <item quantity="many">Скриншот будет сделан через <xliff:g id="NUMBER_1">%d</xliff:g> секунд</item>
+      <item quantity="other">Скриншот будет сделан через <xliff:g id="NUMBER_1">%d</xliff:g> секунды</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Режим без звука"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Выключить"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Включить"</string>
@@ -1063,8 +1065,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Нажмите, чтобы отменить"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Выбор раскладки"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Выбрать раскладку"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Показать способ ввода"</string>
-    <string name="hardware" msgid="7517821086888990278">"Аппаратная"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Показывать на экране, когда физическая клавиатура включена"</string>
+    <string name="hardware" msgid="194658061510127999">"Виртуальная клавиатура"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Выберите раскладку клавиатуры"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Нажмите, чтобы выбрать раскладку клавиатуры."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1567,4 +1569,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Приложение "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хочет добавить пользователя, однако лимит уже достигнут."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"Приложение "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хочет добавить пользователя, однако аккаунт "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" уже есть на этом устройстве. Продолжить?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392">"Приложение "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хочет добавить пользователя для аккаунта "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Продолжить?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Языковые настройки"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Региональные настройки"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Введите язык"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Рекомендуемые"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Все языки"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Поиск"</string>
 </resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index fb36adc..2cbf5ad 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"දෝෂ වර්තාව"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"දෝෂ වාර්තාවක් ගන්න"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ඊ-තැපැල් පණිවිඩයක් ලෙස යැවීමට මෙය ඔබගේ වත්මන් උපාංග තත්වය ගැන තොරතුරු එකතු කරනු ඇත. දෝෂ වාර්තාව ආරම්භ කර එය යැවීමට සූදානම් කරන තෙක් එයට කිසියම් කාලයක් ගතවනු ඇත; කරුණාකර ඉවසන්න."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"අන්තර්ක්‍රියා වාර්."</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"බොහොමයක් වාතාවරණ යටතේ මෙය භාවිත කරන්න. එය ඔබට වාර්තාවේ ප්‍රගතිය හඹා යාමට සහ ගැටලුව පිළිබඳ වැඩිපුර විස්තර ඇතුළත් කිරීමට ඉඩ දෙයි. එය වාර්තා කිරීමට දිගු වේලාවක් ගන්නා සමහර අඩුවෙන්-භාවිත වන කොටස් මග හැරීමට හැකිය."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"සම්පූර්ණ වාර්තාව"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">තත්පර <xliff:g id="NUMBER_1">%d</xliff:g>කින් දෝෂ වාර්තාව සඳහා තිර රුවක් ලබා ගනිමින්</item>
+      <item quantity="other">තත්පර <xliff:g id="NUMBER_1">%d</xliff:g>කින් දෝෂ වාර්තාව සඳහා තිර රුවක් ලබා ගනිමින්</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"නිහඬ ආකාරය"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ශබ්දය අක්‍රියයි"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"හඬ සක්‍රියයි"</string>
@@ -1051,8 +1051,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"අවලංගු කිරීමට ස්පර්ශ කරන්න"</string>
     <string name="select_input_method" msgid="8547250819326693584">"යතුරු පුවරු වෙනස් කිරීම"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"යතුරු පුවරු තෝරන්න"</string>
-    <string name="show_ime" msgid="9157568568695230830">"ආදාන ක්‍රමය පෙන්වන්න"</string>
-    <string name="hardware" msgid="7517821086888990278">"දෘඨාංග"</string>
+    <string name="show_ime" msgid="2506087537466597099">"භෞතික යතුරු පුවරුව සක්‍රිය අතරතුර එය තිරය මත තබා ගන්න"</string>
+    <string name="hardware" msgid="194658061510127999">"අතථ්‍ය යතුරු පුවරුව පෙන්වන්න"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"යතුරු පුවරුවට පිරිසැලැස්ම තෝරන්න"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"යතුරු පුවරුවට පිරිසැලැස්මක් තේරීමට ස්පර්ශ කරන්න."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1533,4 +1533,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" නව පරිශීලකයෙකු එක් කිරීමට උත්සාහ කරමින් සිටින නමුත්, පරිශීලක සීමාවට ළඟා වී ඇත."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" නව පරිශීලකයෙකු එක් කිරීමට උත්සාහ කරමින් සිටී, නමුත් "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ගිණුම මෙම උපාංගය මත දැනටමත් පවතී. කෙසේ වෙතත් ඉදිරියට යන්නද?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" නව පරිශීලකයෙකු "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ගිණුම සඳහා එක් කිරීමට උත්සාහ කරමින් සිටී. ඉදිරියට යන්නද?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"භාෂා මනාප"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"ප්‍රදේශ මනාපය"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"භාෂා නම ටයිප් කරන්න"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"යෝජිත"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"සියලු භාෂා"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"සෙවීම"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index d81e4e73..8e08adc 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -213,15 +213,17 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Hlásenie o chybách"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Vytvoriť hlásenie chyby"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Týmto zhromaždíte informácie o aktuálnom stave zariadenia. Informácie je potom možné odoslať e-mailom, chvíľu však potrvá, kým bude hlásenie chyby pripravené na odoslanie. Prosíme vás preto o trpezlivosť."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktívne nahlásenie"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Táto možnosť je vhodná pre väčšinu prípadov. Umožňuje sledovať priebeh nahlásenia a zadať ďalšie podrobnosti o probléme. Môžu byť vynechané niektoré menej používané sekcie, ktorých nahlásenie trvá dlho."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Úplné nahlásenie"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="few">Snímka obrazovky pre hlásenie chyby sa vytvorí o <xliff:g id="NUMBER_1">%d</xliff:g> sekundy.</item>
+      <item quantity="many">Snímka obrazovky pre hlásenie chyby sa vytvorí o <xliff:g id="NUMBER_1">%d</xliff:g> sekundy.</item>
+      <item quantity="other">Snímka obrazovky pre hlásenie chyby sa vytvorí o <xliff:g id="NUMBER_1">%d</xliff:g> sekúnd.</item>
+      <item quantity="one">Snímka obrazovky pre hlásenie chyby sa vytvorí o <xliff:g id="NUMBER_0">%d</xliff:g> sekundu.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tichý režim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je VYPNUTÝ."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je zapnutý"</string>
@@ -1063,8 +1065,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Dotykom zrušíte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Zmeniť klávesnicu"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vybrať klávesnicu"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Zobraziť metódu vstupu"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardvér"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Ponechať na obrazovke, keď je aktívna fyzická klávesnica"</string>
+    <string name="hardware" msgid="194658061510127999">"Zobraziť virtuálnu klávesnicu"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Zvoľte rozloženie klávesnice"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotykom zvoľte rozloženie klávesnice."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
@@ -1567,4 +1569,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Aplikácia "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sa pokúša pridať nového používateľa, bol však prekročený limit počtu používateľov."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"Aplikácia "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sa pokúša pridať nového používateľa, účet "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" však na tomto zariadení už existuje. Chcete napriek tomu pokračovať?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392">"Aplikácia "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sa pokúša pridať nového používateľa pre účet "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Chcete pokračovať?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Jazykové predvoľby"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferovaný región"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Zadajte názov jazyka"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Navrhované"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Všetky jazyky"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Vyhľadávanie"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index c86227e..c85f7b5 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -213,15 +213,17 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Poročilo o napakah"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Ustvari poročilo o napakah"</string>
     <string name="bugreport_message" msgid="398447048750350456">"S tem bodo zbrani podatki o trenutnem stanju naprave, ki bodo poslani v e-poštnem sporočilu. Izvedba poročila o napakah in priprava trajata nekaj časa, zato bodite potrpežljivi."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktivno poročilo"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"To možnost uporabite v večini primerov. Omogoča sledenje napredka poročila in vnos več podrobnosti o težavi. Morda bodo izpuščeni nekateri redkeje uporabljani razdelki, za katere je poročanje dolgotrajno."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Celotno poročilo"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Posnetek zaslona za poročilo o napakah bo narejen čez <xliff:g id="NUMBER_1">%d</xliff:g> s.</item>
+      <item quantity="two">Posnetek zaslona za poročilo o napakah bo narejen čez <xliff:g id="NUMBER_1">%d</xliff:g> s.</item>
+      <item quantity="few">Posnetek zaslona za poročilo o napakah bo narejen čez <xliff:g id="NUMBER_1">%d</xliff:g> s.</item>
+      <item quantity="other">Posnetek zaslona za poročilo o napakah bo narejen čez <xliff:g id="NUMBER_1">%d</xliff:g> s.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tihi način"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvok je IZKLOPLJEN"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvok je VKLOPLJEN"</string>
@@ -1063,8 +1065,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Če želite prekiniti, se dotaknite"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Sprememba tipkovnice"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Izbira tipkovnic"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Pokaži način vnosa"</string>
-    <string name="hardware" msgid="7517821086888990278">"Strojna oprema"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Ohrani na zaslonu, dokler je aktivna fizična tipkovnica"</string>
+    <string name="hardware" msgid="194658061510127999">"Pokaži navidezno tipkovnico"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Izberite razporeditev tipkovnice"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotaknite se, da izberete razporeditev tipkovnice"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1567,4 +1569,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Aplikacija "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" poskuša dodati novega uporabnika, vendar je dosežena omejitev števila uporabnikov."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"Aplikacija "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" poskuša dodati novega uporabnika, vendar račun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" v napravi že obstaja. Ali želite kljub temu nadaljevati?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392">"Aplikacija "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" poskuša dodati novega uporabnika za račun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Ali želite nadaljevati?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Nastavitev jezika"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Nastavitev območja"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Vnesite ime jezika"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Predlagano"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Vsi jeziki"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Išči"</string>
 </resources>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index c33dc5b..65156f0 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Raporti i defekteve në kod"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Merr raportin e defekteve në kod"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ky funksion mundëson mbledhjen e informacioneve mbi gjendjen aktuale të pajisjes për ta dërguar si mesazh mail-i. Do të duhet pak kohë nga nisja e raportit të defekteve në kod. Faleminderit për durimin."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Raport interaktiv"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Përdore këtë në shumicën e rrethanave. Të lejon të gjurmosh progresin e raportit dhe të fusësh më shumë detaje rreth problemit. Mund të fshijë disa seksione që përdoren më pak të cilat kërkojnë shumë kohë për t\'u raportuar."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Raporti i plotë"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Marrja e pamjes së ekranit për raportin e defektit në kod në <xliff:g id="NUMBER_1">%d</xliff:g> sekonda.</item>
+      <item quantity="one">Marrja e pamjes së ekranit për raportin e defektit në kod në <xliff:g id="NUMBER_0">%d</xliff:g> sekondë.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modaliteti \"në heshtje\""</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zëri është çaktivizuar"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zëri është i aktivizuar"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Prek për ta anuluar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Ndërro tastierë"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Zgjidh tastierat"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Shfaq metodën e hyrjes"</string>
-    <string name="hardware" msgid="7517821086888990278">"Harduer"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Mbaje në ekran ndërsa tastiera fizike është aktive"</string>
+    <string name="hardware" msgid="194658061510127999">"Shfaq tastierën virtuale"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Përzgjidh planin e tastierës"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Prek për të përzgjedhur tastierën."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" po përpiqet të shtojë një përdorues të ri, por është arritur limiti i përdoruesve."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" po provon të shtojë një përdorues të ri, por llogaria "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ekziston tashmë në këtë pajisje. Dëshiron të vazhdosh gjithsesi?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" po provon të shtojë një përdorues të ri për llogarinë "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Dëshiron të vazhdosh?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Preferenca për gjuhën"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Preferenca e rajonit"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Shkruaj emrin e gjuhës"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Sugjeruar"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Të gjitha gjuhët"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Kërko"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 04a170c..fe7b0d7 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -212,15 +212,16 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Извештај о грешци"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Направи извештај о грешци"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Овим ће се прикупити информације о тренутном стању уређаја како би биле послате у поруци е-поште. Од започињања извештаја о грешци до тренутка за његово слање проћи ће неко време; будите стрпљиви."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактив. извештај"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Користите ово у већини случајева. То вам омогућава да пратите напредак извештаја и да уносите додатне детаље о проблему. Вероватно ће изоставити неке мање коришћене одељке за које прављење извештаја дуго траје."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Комплетан извештај"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Направићемо снимак екрана ради извештаја о грешци за <xliff:g id="NUMBER_1">%d</xliff:g> секунду.</item>
+      <item quantity="few">Направићемо снимак екрана ради извештаја о грешци за <xliff:g id="NUMBER_1">%d</xliff:g> секунде.</item>
+      <item quantity="other">Направићемо снимак екрана ради извештаја о грешци за <xliff:g id="NUMBER_1">%d</xliff:g> секунди.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Нечујни режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звук је ИСКЉУЧЕН"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звук је УКЉУЧЕН"</string>
@@ -1056,8 +1057,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Додирните да бисте отказали"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Промените тастатуру"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Изаберите тастатуре"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Приказивање метода уноса"</string>
-    <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Задржи га на екрану док је физичка тастатура активна"</string>
+    <string name="hardware" msgid="194658061510127999">"Прикажи виртуелну тастатуру"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Избор распореда тастатуре"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Додирните да бисте изабрали распоред тастатуре."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1549,4 +1550,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" покушава да дода новог корисника, али је ограничење за број корисника достигнуто."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" покушава да дода новог корисника, али налог "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" већ постоји на овом уређају. Желите ли ипак да наставите?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" покушава да дода новог корисника за налог "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Желите ли да наставите?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Подешавање језика"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Подешавање региона"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Унесите назив језика"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Предложени"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Сви језици"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Претражи"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 346b1234..d80b4c2 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Felrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Skapa felrapport"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Nu hämtas information om aktuell status för enheten, som sedan skickas i ett e-postmeddelade. Det tar en liten stund innan felrapporten är färdig och kan skickas, så vi ber dig ha tålamod."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv rapport"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Bör användas i de flesta fall. Då kan du spåra rapportförloppet och ange mer information om problemet. En del mindre använda avsnitt, som det tar lång tid att rapportera om, kan uteslutas."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Fullständig rapport"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Tar en skärmdump till felrapporten om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder.</item>
+      <item quantity="one">Tar en skärmdump till felrapporten om <xliff:g id="NUMBER_0">%d</xliff:g> sekund.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tyst läge"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ljudet är AV"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ljudet är PÅ"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tryck här om du vill avbryta"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Byt tangentbord"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Välj tangentbord"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Visa inmatningsmetod"</string>
-    <string name="hardware" msgid="7517821086888990278">"Maskinvara"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Ha kvar den på skärmen när det fysiska tangentbordet används"</string>
+    <string name="hardware" msgid="194658061510127999">"Visa virtuellt tangentbord"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Välj en tangentbordslayout"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Välj en tangentbordslayout genom att trycka."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" försöker lägga till en ny användare, men gränsen för antal användare har uppnåtts."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" försöker lägga till en ny användare, men kontot "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" finns redan på den här enheten. Vill du fortsätta ändå?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" försöker lägga till en ny användare för kontot "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vill du fortsätta?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Språkinställning"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Regionsinställningar"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Ange språket"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Förslag"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Alla språk"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Söka"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 714827c..5ae50b8 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -213,15 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ripoti ya hitilafu"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Chukua ripoti ya hitilafu"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Hii itakusanya maelezo kuhusu hali ya kifaa chako kwa sasa, na itume kama barua pepe. Itachukua muda mfupi tangu ripoti ya hitilafu ianze kuzalishwa hadi iwe tayari kutumwa; vumilia."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Ripoti ya kushirikiana"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Itumie katika hali nyingi. Inakuruhusu kufuatilia maendeleo ya ripoti na kuweka maelezo zaidi kuhusu tatizo. Huenda ikaondoa sehemu ambazo hazitumiki sana, ambazo huchukua muda mrefu kuripoti."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Ripoti kamili"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Inapiga picha ya skrini ili iripoti hitilafu baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>.</item>
+      <item quantity="one">Inapiga picha ya skrini ili iripoti hitilafu baada ya sekunde <xliff:g id="NUMBER_0">%d</xliff:g>.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mtindo wa kimya"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sauti Imezimwa"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sauti imewashwa"</string>
@@ -1051,8 +1051,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Gusa ili ufute"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Badilisha kibodi"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Chagua kibodi"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Onyesha mbinu ya kuingiza"</string>
-    <string name="hardware" msgid="7517821086888990278">"Maunzi"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Iweke kwenye skrini wakati kibodi inapotumika"</string>
+    <string name="hardware" msgid="194658061510127999">"Onyesha kibodi pepe"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Teua mpangilio wa kibodi"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Gusa ili kuchagua mpangilio wa kibodi."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1533,4 +1533,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" inajaribu kuongeza mtumiaji mpya, lakini idadi ya juu ya watumiaji imefikiwa."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" inajaribu kuongeza mtumiaji mpya, lakini akaunti ya "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" tayari ipo kwenye kifaa hiki. Ungependa kundelea?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" inajaribu kuongeza mtumiaji mpya kwenye akaunti ya "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Ungependa kuendelea?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Lugha ninayopendelea"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Mapendeleo ya eneo"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Weka jina la lugha"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Inayopendekezwa"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Lugha zote"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Tafuta"</string>
 </resources>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 38c2e26..4671344 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"பிழை அறிக்கை"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"பிழை அறிக்கையை எடு"</string>
     <string name="bugreport_message" msgid="398447048750350456">"உங்கள் நடப்புச் சாதன நிலையை மின்னஞ்சல் செய்தியாக அனுப்ப, அது குறித்த தகவலை இது சேகரிக்கும். பிழை அறிக்கையைத் தொடங்குவதில் இருந்து, அது அனுப்புவதற்குத் தயாராகும் வரை, இதற்குச் சிறிது நேரம் ஆகும்; பொறுமையாகக் காத்திருக்கவும்."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ஊடாடத்தக்க அறிக்கை"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"பெரும்பாலான சூழ்நிலைகளில் இதைப் பயன்படுத்தவும். இது அறிக்கையின் நிலையைக் கண்காணிக்கவும், சிக்கலைப் பற்றிய மேலும் விவரங்களை உள்ளிடவும் அனுமதிக்கும். அறிக்கையிட நீண்ட நேரம் எடுக்கக்கூடிய குறைவாகப் பயன்படுத்தப்படும் பிரிவுகள் சிலவற்றை இது தவிர்க்கக்கூடும்."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"முழு அறிக்கை"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> வினாடிகளில் பிழை அறிக்கைக்கான ஸ்கிரீன் ஷாட் எடுக்கப்படும்.</item>
+      <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> வினாடியில் பிழை அறிக்கைக்கான ஸ்கிரீன் ஷாட் எடுக்கப்படும்.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"நிசப்த பயன்முறை"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ஒலி முடக்கத்தில் உள்ளது"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ஒலி இயக்கத்தில் உள்ளது"</string>
@@ -1044,13 +1044,13 @@
     <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"பிழை அறிக்கையை நிர்வாகியுடன் பகிரவா?"</string>
     <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"பிழைகாண்பதற்கு உதவ, உங்கள் ஐடி நிர்வாகி பிழை அறிக்கையைக் கோரியுள்ளார்"</string>
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"சரி"</string>
-    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"நிராகரி"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"வேண்டாம்"</string>
     <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"பிழை அறிக்கையை எடுக்கிறது…"</string>
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ரத்துசெய்ய, தொடவும்"</string>
     <string name="select_input_method" msgid="8547250819326693584">"விசைப்பலகையை மாற்று"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"விசைப்பலகைகளைத் தேர்வுசெய்க"</string>
-    <string name="show_ime" msgid="9157568568695230830">"உள்ளீட்டு முறையைக் காட்டு"</string>
-    <string name="hardware" msgid="7517821086888990278">"வன்பொருள்"</string>
+    <string name="show_ime" msgid="2506087537466597099">"கைமுறை விசைப்பலகை இயக்கத்தில் இருக்கும் போது IMEஐ திரையில் வைத்திரு"</string>
+    <string name="hardware" msgid="194658061510127999">"விர்ச்சுவல் விசைப்பலகையை காட்டு"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"விசைப்பலகைத் தளவமைப்பைத் தேர்ந்தெடுக்கவும்"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"விசைப்பலகைத் தளவமைப்பைத் தேர்ந்தெடுக்க தொடவும்."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" பயன்பாடு புதிய பயனரைச் சேர்க்க முயல்கிறது, ஆனால் பயனருக்கான வரம்பு முடிந்துவிட்டது."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" பயன்பாடு புதிய பயனரைச் சேர்க்க முயல்கிறது. ஆனால் "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" கணக்கு ஏற்கனவே இந்தச் சாதனத்தில் உள்ளது. தொடரவா?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" பயன்பாடு "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" கணக்கிற்குப் புதிய பயனரைச் சேர்க்க முயல்கிறது. தொடரவா?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"மொழி விருப்பம்"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"மண்டல விருப்பம்"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"மொழி பெயரை உள்ளிடுக"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"பரிந்துரைகள்"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"எல்லா மொழிகளும்"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"தேடு"</string>
 </resources>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 14cc2c1..8535b9c 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"బగ్ నివేదిక"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"బగ్ నివేదికను సిద్ధం చేయి"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ఇది ఇ-మెయిల్ సందేశం రూపంలో పంపడానికి మీ ప్రస్తుత పరికర స్థితి గురించి సమాచారాన్ని సేకరిస్తుంది. బగ్ నివేదికను ప్రారంభించడం మొదలుకొని పంపడానికి సిద్ధం చేసే వరకు ఇందుకు కొంత సమయం పడుతుంది; దయచేసి ఓపిక పట్టండి."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ప్రభావశీల నివేదిక"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"చాలా సందర్భాల్లో ఇది ఉపయోగించబడుతుంది. ఇది మిమ్మల్ని నివేదిక ప్రోగ్రెస్ ట్రాక్ చేయడానికి మరియు సమస్య గురించి మరిన్ని వివరాలను నమోదు చేయడానికి అనుమతిస్తుంది. ఇది నివేదించడానికి అధిక సమయం పట్టే తక్కువగా వినియోగించే విభాగాలను విడిచిపెట్టవచ్చు."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"పూర్తి నివేదిక"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">బగ్ నివేదిక కోసం <xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో స్క్రీన్‌షాట్ తీయబోతోంది.</item>
+      <item quantity="one">బగ్ నివేదిక కోసం <xliff:g id="NUMBER_0">%d</xliff:g> సెకనులో స్క్రీన్‌షాట్ తీయబోతోంది.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"నిశ్శబ్ద మోడ్"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ధ్వని ఆఫ్‌లో ఉంది"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ధ్వని ఆన్‌లో ఉంది"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"రద్దు చేయడానికి తాకండి"</string>
     <string name="select_input_method" msgid="8547250819326693584">"కీబోర్డ్‌ను మార్చు"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"కీబోర్డ్‌లను ఎంచుకోండి"</string>
-    <string name="show_ime" msgid="9157568568695230830">"ఇన్‌పుట్ పద్ధతిని చూపు"</string>
-    <string name="hardware" msgid="7517821086888990278">"హార్డ్‌వేర్"</string>
+    <string name="show_ime" msgid="2506087537466597099">"దీన్ని భౌతిక కీబోర్డ్ సక్రియంగా ఉన్నప్పుడు స్క్రీన్‌పై ఉంచుతుంది"</string>
+    <string name="hardware" msgid="194658061510127999">"వర్చువల్ కీబోర్డ్‌ను చూపు"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"కీబోర్డ్ లేఅవుట్‌ను ఎంచుకోండి"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"కీబోర్డ్ లేఅవుట్‌ను ఎంచుకోవడానికి తాకండి."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" కొత్త వినియోగదారుని జోడించడానికి ప్రయత్నిస్తోంది, కానీ వినియోగదారు పరిమితి చేరుకుంది."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" కొత్త వినియోగదారుని జోడించడానికి ప్రయత్నిస్తోంది, కానీ ఖాతా "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ఇప్పటికే ఈ పరికరంలో ఉంది. ఏదేమైనా కొనసాగించాలా?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ఖాతా "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" కోసం కొత్త వినియోగదారుని జోడించడానికి ప్రయత్నిస్తోంది. కొనసాగించాలా?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"భాష ప్రాధాన్యత"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"ప్రాంతం ప్రాధాన్యత"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"భాష పేరును టైప్ చేయండి"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"సూచించినవి"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"అన్ని భాషలు"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"శోధించు"</string>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 59f6ffa..a759145 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"รายงานข้อบกพร่อง"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ใช้รายงานข้อบกพร่อง"</string>
     <string name="bugreport_message" msgid="398447048750350456">"การดำเนินการนี้จะรวบรวมข้อมูลเกี่ยวกับสถานะปัจจุบันของอุปกรณ์ของคุณ โดยจะส่งไปในรูปแบบข้อความอีเมล อาจใช้เวลาสักครู่ตั้งแต่เริ่มการสร้างรายงานข้อบกพร่องจนกระทั่งเสร็จสมบูรณ์ โปรดอดทนรอ"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"รายงานแบบอินเทอร์แอกทีฟ"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"ใช้ตัวเลือกนี้ได้เกือบทุกสถานการณ์ โดยจะอนุญาตให้คุณติดตามความคืบหน้าของรายงานและป้อนรายละเอียดเพิ่มเติมของปัญหา หัวข้อที่ใช้งานน้อยแต่ใช้เวลานานในการรายงานอาจถูกข้ามไป"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"รายงานฉบับเต็ม"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">จะจับภาพหน้าจอสำหรับรายงานข้อบกพร่องใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที</item>
+      <item quantity="one">จะจับภาพหน้าจอสำหรับรายงานข้อบกพร่องใน <xliff:g id="NUMBER_0">%d</xliff:g> วินาที</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"โหมดปิดเสียง"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ปิดเสียงไว้"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"เปิดเสียงแล้ว"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"แตะเพื่อยกเลิก"</string>
     <string name="select_input_method" msgid="8547250819326693584">"เปลี่ยนแป้นพิมพ์"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"เลือกแป้นพิมพ์"</string>
-    <string name="show_ime" msgid="9157568568695230830">"แสดงวิธีการป้อนข้อมูล"</string>
-    <string name="hardware" msgid="7517821086888990278">"ฮาร์ดแวร์"</string>
+    <string name="show_ime" msgid="2506087537466597099">"เปิดทิ้งไว้บนหน้าจอในระหว่างใช้งานแป้นพิมพ์จริง"</string>
+    <string name="hardware" msgid="194658061510127999">"แสดงแป้นพิมพ์เสมือน"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"เลือกรูปแบบแป้นพิมพ์"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"แตะเพื่อเลือกรูปแบบแป้นพิมพ์"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" กำลังพยายามเพิ่มผู้ใช้ใหม่ แต่ถึงขีดจำกัดของผู้ใช้แล้ว"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" กำลังพยายามเพิ่มผู้ใช้ใหม่ แต่มีบัญชี "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" อยู่แล้วบนอุปกรณ์เครื่องนี้ ดำเนินการต่อไหม"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" กำลังพยายามเพิ่มผู้ใช้ใหม่สำหรับบัญชี "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ดำเนินการต่อไหม"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"ค่ากำหนดภาษา"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"ค่ากำหนดภูมิภาค"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"พิมพ์ชื่อภาษา"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"แนะนำ"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ทุกภาษา"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"ค้นหา"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index c6e643b..b5e1de8 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ulat sa bug"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Kunin ang ulat sa bug"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Mangongolekta ito ng impormasyon tungkol sa kasalukuyang katayuan ng iyong device, na ipapadala bilang mensaheng e-mail. Gugugol ito ng kaunting oras mula sa pagsisimula ng ulat sa bug hanggang sa handa na itong maipadala; mangyaring magpasensya."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive na ulat"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Gamitin ito sa karamihan ng sitwasyon. Nagbibigay-daan ito sa iyo na subaybayan ang pag-usad ng ulat at magbigay ng higit pang mga detalye tungkol sa problema. Maaari itong mag-alis ng ilan sa mga hindi masyadong ginagamit na seksyon na nangangailangan ng mahabang panahon upang iulat."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Buong ulat"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Kukuha ng screenshot para sa ulat ng bug sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> segundo.</item>
+      <item quantity="other">Kukuha ng screenshot para sa ulat ng bug sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> na segundo.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Naka-OFF ang tunog"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Naka-ON ang sound"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Pindutin upang kanselahin"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Baguhin ang keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pumili ng mga keyboard"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Ipakita ang pamamaraan ng pag-input"</string>
-    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Panatilihin ito sa screen habang aktibo ang pisikal na keyboard"</string>
+    <string name="hardware" msgid="194658061510127999">"Ipakita ang virtual keyboard"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pumili ng layout ng keyboard"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Pindutin upang pumili ng layout ng keyboard."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Sinusubukan ng "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" na magdagdag ng bagong user, ngunit naabot na ang limitasyon sa user."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789">"Sinusubukan ng "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" na magdagdag ng bagong user, ngunit nasa device na ito na ang account na "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Magpatuloy pa rin?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392">"Sinusubukan ng "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" na magdagdag ng bagong user para sa account na "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Magpatuloy?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Kagustuhan sa wika"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Kagustuhan sa rehiyon"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"I-type ang wika"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Iminumungkahi"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Lahat ng wika"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Maghanap"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 3603952..79a5c54 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Hata raporu"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Hata raporu al"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Bu rapor, e-posta iletisi olarak göndermek üzere cihazınızın şu anki durumuyla ilgili bilgi toplar. Hata raporu başlatıldıktan sonra hazır olması biraz zaman alabilir, lütfen sabırlı olun."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Etkileşimli rapor"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Çoğu durumda bunu kullanın. Bu seçenek, raporun ilerleme durumunu takip etmenize ve sorunla ilgili daha fazla ayrıntı girmenize olanak sağlar. Rapor edilmesi uzun süren ve az kullanılan bazı bölümleri yok sayabilir."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Tam rapor"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde hata raporu ekran görüntüsü alınıyor.</item>
+      <item quantity="one">Hata raporu ekran görüntüsü <xliff:g id="NUMBER_0">%d</xliff:g> saniye içinde alınacak.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Sessiz mod"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ses KAPALI"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ses AÇIK"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"İptal etmek için dokunun"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klavyeyi değiştir"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klavyeyi seç"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Giriş yöntemini göster"</string>
-    <string name="hardware" msgid="7517821086888990278">"Donanım"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Fiziksel klavye etkin durumdayken ekranda tut"</string>
+    <string name="hardware" msgid="194658061510127999">"Sanal klavyeyi göster"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Klavye düzeni seçin"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Bir klavye düzeni seçmek için dokunun."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", yeni bir kullanıcı eklemeye çalışıyor, ancak kullanıcı sınırına ulaşıldı."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", yeni bir kullanıcı eklemeye çalışıyor, ancak "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hesabı bu cihazda zaten var. Yine de devam edilsin mi?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hesabı için yeni bir kullanıcı eklemeye çalışıyor. Devam edilsin mi?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Dil tercihi"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Bölge tercihi"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Dil adını yazın"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Önerilen"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Tüm diller"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Ara"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index fdc6323..f4ba226 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -213,15 +213,17 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Звіт про помилки"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Звіт про помилку"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Інформація про поточний стан вашого пристрою буде зібрана й надіслана електронною поштою. Підготовка звіту триватиме певний час."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Інтерактивний звіт"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Підходить для більшості випадків. Можна відстежувати, як створюється звіт, і вводити більше деталей про проблему. Можуть опускатися деякі розділи, які рідко використовуються, але довго створюються."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Повний звіт"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Знімок екрана для звіту про помилки буде зроблено через <xliff:g id="NUMBER_1">%d</xliff:g> секунду.</item>
+      <item quantity="few">Знімок екрана для звіту про помилки буде зроблено через <xliff:g id="NUMBER_1">%d</xliff:g> секунди.</item>
+      <item quantity="many">Знімок екрана для звіту про помилки буде зроблено через <xliff:g id="NUMBER_1">%d</xliff:g> секунд.</item>
+      <item quantity="other">Знімок екрана для звіту про помилки буде зроблено через <xliff:g id="NUMBER_1">%d</xliff:g> секунди.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Беззвуч. режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звук ВИМК."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звук УВІМК."</string>
@@ -1063,8 +1065,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Торкніться, щоб скасувати"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Змінити клавіатуру"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Вибрати клавіатури"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Показати метод введення"</string>
-    <string name="hardware" msgid="7517821086888990278">"Обладнання"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Утримуйте на екрані, коли активна фізична клавіатура"</string>
+    <string name="hardware" msgid="194658061510127999">"Показати віртуальну клавіатуру"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Виберіть розкладку клавіатури"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Торкніться, щоб вибрати розкладку клавіатури."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
@@ -1567,4 +1569,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хоче додати нового користувача, але вже додано максимальну кількість користувачів."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хоче додати нового користувача, але обліковий запис "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" уже існує на цьому пристрої. Продовжити?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хоче додати нового користувача облікового запису "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Продовжити?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Вибір мови"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Вибір регіону"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Введіть назву мови"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Пропозиції"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Усі мови"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Пошук"</string>
 </resources>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 14167ac..bf2f989 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"بگ کی اطلاع"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"بگ کی اطلاع لیں"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ایک ای میل پیغام کے بطور بھیجنے کیلئے، یہ آپ کے موجودہ آلہ کی حالت کے بارے میں معلومات جمع کرے گا۔ بگ کی اطلاع شروع کرنے سے لے کر بھیجنے کیلئے تیار ہونے تک اس میں تھوڑا وقت لگے گا؛ براہ کرم تحمل سے کام لیں۔"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"متعامل رپورٹ"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"زیادہ تر حالات میں اسے استعمال کریں۔ یہ آپ کو رپورٹ کی پیش رفت ٹریک کرنے اور مسئلہ سے متعلق زیادہ تفصیلات میں جانے کی اجازت دیتا ہے۔ شاید یہ کچھ ایسے کم استعمال ہونے والے سیکشنز کو خارج کر دے جو رپورٹ کرنے میں زیادہ وقت لگاتے ہیں۔"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"مکمل رپورٹ"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">بگ رپورٹ کیلئے <xliff:g id="NUMBER_1">%d</xliff:g> سیکنڈز میں اسکرین شاٹ لیا جائے گا۔</item>
+      <item quantity="one">بگ رپورٹ کیلئے <xliff:g id="NUMBER_0">%d</xliff:g> سیکنڈ میں اسکرین شاٹ لیا جائے گا۔</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"خاموش وضع"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"آواز آف ہے"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"آواز آن ہے"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"منسوخ کرنے کیلئے ٹچ کریں"</string>
     <string name="select_input_method" msgid="8547250819326693584">"کی بورڈ تبدیل کریں"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"کی بورڈز منتخب کریں"</string>
-    <string name="show_ime" msgid="9157568568695230830">"ان پٹ طریقہ دکھائیں"</string>
-    <string name="hardware" msgid="7517821086888990278">"ہارڈ ویئر"</string>
+    <string name="show_ime" msgid="2506087537466597099">"‏جب فزیکل کی بورڈ فعال ہو تو IME کو اسکرین پر رکھیں"</string>
+    <string name="hardware" msgid="194658061510127999">"ورچوئل کی بورڈ دکھائیں"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"کی بورڈ کا خاکہ منتخب کریں"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ایک کی بورڈ کا خاکہ منتخب کرنے کیلئے چھوئیں۔"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ایک نیا صارف شامل کرنے کی کوشش کر رہی ہے، لیکن صارف کی حد پوری ہوگئی ہے۔"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ایک نیا صارف شامل کرنے کی کوشش کر رہی ہے لیکن اکاؤنٹ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" پہلے سے اس آلہ پر موجود ہے۔ بہر صورت آگے بڑھیں؟"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" اکاؤنٹ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" کیلئے ایک نیا صارف شامل کرنے کی کوشش کر رہی ہے۔ آگے بڑھیں؟"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"زبان کی ترجیح"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"علاقہ کی ترجیح"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"زبان کا نام ٹائپ کریں"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"تجویز کردہ"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"سبھی زبانیں"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"تلاش"</string>
 </resources>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index e904573..a33a283 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Nosozlik haqida ma’lumot berish"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Xatoliklar hisoboti"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Qurilmangiz holati haqidagi ma’lumotlar to‘planib, e-pochta orqali yuboriladi. Hisobotni tayyorlash biroz vaqt olishi mumkin."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv hisobot"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Bundan maxsus vaziyatlarda foydalaning. Bu hisobot jarayonini kuzatish imkonini beradi va muammo haqida batafsil ma’lumotlarni ko‘rishingiz mumkin bo‘ladi. Hisobot uchun ko‘p vaqt oladigan kam ishlatiladigan bo‘limlar qoldirib ketilishi mumkin."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"To‘liq hisobot"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Xatoliklar hisoboti uchun skrinshot <xliff:g id="NUMBER_1">%d</xliff:g> soniyadan so‘ng olinadi.</item>
+      <item quantity="one">Xatoliklar hisoboti uchun skrinshot <xliff:g id="NUMBER_0">%d</xliff:g> soniyadan so‘ng olinadi.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Ovozsiz rejim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Tovush o‘chirilgan"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"YONIQ"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Bekor qilish uchun bosing"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviaturani o‘zgartirish"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturani tanlash"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Kiritish usulini ko‘rish"</string>
-    <string name="hardware" msgid="7517821086888990278">"Qurilma"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Tashqi klaviaturadan foydalanilayotganda buni ekranda saqlab turish"</string>
+    <string name="hardware" msgid="194658061510127999">"Virtual klaviatura ko‘rsatilsin"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Tugmalar tartibini tanlash"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Tugmalar tartibini tanlash uchun bosing."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ilovasi yangi foydalanuvchi qo‘shishga urinmqoda, lekin ortiq foydalanuvchi qo‘shib bo‘lmaydi."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ilovasi yangi foydalanuvchi qo‘shishga urinmoqda, lekin "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hisobi allaqachon qurilmada mavjud. Baribir davom etilsinmi?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ilovasi "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hisobi uchun yangi foydalanuvchi qo‘shishga urinmoqda. Davom etilsinmi?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Til sozlamalari"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Hudud sozlamalari"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Til nomini kiriting"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Taklif etiladi"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Barcha tillar"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Qidiruv"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index c979b3c4..56af67d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Báo cáo lỗi"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Nhận báo cáo lỗi"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Báo cáo này sẽ thu thập thông tin về tình trạng thiết bị hiện tại của bạn, để gửi dưới dạng thông báo qua email. Sẽ mất một chút thời gian kể từ khi bắt đầu báo cáo lỗi cho tới khi báo cáo sẵn sàng để gửi; xin vui lòng kiên nhẫn."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Báo cáo tương tác"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Sử dụng tùy chọn này trong hầu hết các trường hợp. Tùy chọn này cho phép bạn theo dõi tiến trình của báo cáo và nhập thêm thông tin chi tiết về sự cố. Tùy chọn này có thể bỏ qua một số phần ít được sử dụng mà mất nhiều thời gian để báo cáo."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Báo cáo đầy đủ"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">Sẽ chụp ảnh màn hình để báo cáo lỗi sau <xliff:g id="NUMBER_1">%d</xliff:g> giây.</item>
+      <item quantity="one">Sẽ chụp ảnh màn hình để báo cáo lỗi sau <xliff:g id="NUMBER_0">%d</xliff:g> giây.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Chế độ im lặng"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Âm thanh TẮT"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Âm thanh BẬT"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Chạm để hủy"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Thay đổi bàn phím"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Chọn bàn phím"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Hiển thị phương thức nhập"</string>
-    <string name="hardware" msgid="7517821086888990278">"Phần cứng"</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>
+    <string name="hardware" msgid="194658061510127999">"Hiển thị bàn phím ảo"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Chọn bố cục bàn phím"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Chạm để chọn bố cục bàn phím."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" đang cố thêm người dùng mới nhưng đã đạt đến giới hạn người dùng."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" đang cố thêm người dùng mới nhưng tài khoản "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" đã tồn tại trên thiết bị này. Vẫn tiếp tục?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" đang cố thêm người dùng mới cho tài khoản "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Tiếp tục?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Tùy chọn ngôn ngữ"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Tùy chọn khu vực"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Nhập tên ngôn ngữ"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Ðược đề xuất"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Tất cả ngôn ngữ"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Tìm kiếm"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index fd12d29..45d13e8 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"错误报告"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"提交错误报告"</string>
     <string name="bugreport_message" msgid="398447048750350456">"这会收集有关当前设备状态的信息,并以电子邮件的形式进行发送。从开始生成错误报告到准备好发送需要一点时间,请耐心等待。"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"互动式报告"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"在大多数情况下,建议您使用此选项,以便追踪报告的生成进度,以及输入与相应问题相关的更多详细信息。系统可能会省略掉一些不常用的区段,从而缩短生成报告的时间。"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"完整报告"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">系统将在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后对错误报告进行截屏。</item>
+      <item quantity="one">系统将在 <xliff:g id="NUMBER_0">%d</xliff:g> 秒后对错误报告进行截屏。</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"静音模式"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"声音已关闭"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"声音已开启"</string>
@@ -238,9 +238,9 @@
     <string name="user_owner_label" msgid="2804351898001038951">"个人"</string>
     <string name="managed_profile_label" msgid="6260850669674791528">"工作"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"通讯录"</string>
-    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"使用您的通讯录"</string>
+    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"访问您的通讯录"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"位置信息"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"使用此设备的位置信息"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"获取此设备的位置信息"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"日历"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"访问您的日历"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"短信"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"触摸可取消"</string>
     <string name="select_input_method" msgid="8547250819326693584">"更改键盘"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"选择键盘"</string>
-    <string name="show_ime" msgid="9157568568695230830">"显示输入法"</string>
-    <string name="hardware" msgid="7517821086888990278">"硬件"</string>
+    <string name="show_ime" msgid="2506087537466597099">"连接到实体键盘时使其在屏幕上保持显示状态"</string>
+    <string name="hardware" msgid="194658061510127999">"显示虚拟键盘"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"选择键盘布局"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"触摸可选择键盘布局。"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"正尝试添加新用户,但已达到用户人数上限。"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"正尝试添加新用户,但这个设备上已经存在"<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"这个帐号。仍要继续吗?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"正尝试为"<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"这个帐号添加新用户,要继续吗?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"语言偏好设置"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"区域偏好设置"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"输入语言名称"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"建议语言"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"所有语言"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"搜索"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index bd6ec0a..2fe2228 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"取得錯誤報告"</string>
     <string name="bugreport_message" msgid="398447048750350456">"這會收集您目前裝置狀態的相關資訊,並以電郵傳送給您。從開始建立錯誤報告到準備傳送需要一段時間,請耐心等候。"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"互動報告"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"在大部分情況下,建議您使用此選項,以便追蹤報告進度,以及輸入更多與問題相關的的資訊。系統可能會省略部分不常用的區段,藉此縮短產生報告的時間。"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"完整報告"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">系統將在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後擷取錯誤報告的螢幕畫面。</item>
+      <item quantity="one">系統將在 <xliff:g id="NUMBER_0">%d</xliff:g> 秒後擷取錯誤報告的螢幕畫面。</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"靜音模式"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"關閉音效"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"音效已開啟"</string>
@@ -248,7 +248,7 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"儲存空間"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"在您的裝置上存取相片、媒體和檔案"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"麥克風"</string>
-    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"錄製語音訊息"</string>
+    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"錄音"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"相機"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"拍照和錄製影片"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"輕觸即可取消"</string>
     <string name="select_input_method" msgid="8547250819326693584">"變更鍵盤"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"選擇鍵盤"</string>
-    <string name="show_ime" msgid="9157568568695230830">"顯示輸入法"</string>
-    <string name="hardware" msgid="7517821086888990278">"硬件"</string>
+    <string name="show_ime" msgid="2506087537466597099">"在實體鍵盤處於連接狀態時保持顯示"</string>
+    <string name="hardware" msgid="194658061510127999">"顯示虛擬鍵盤"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"選取鍵盤配置"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"輕觸即可選取鍵盤配置。"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" 正在嘗試新增使用者,但使用者人數已達上限。"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" 正在嘗試新增使用者,但此裝置上已有 "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" 這個帳戶。仍要繼續嗎?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" 正在嘗試為 "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" 這個帳戶新增使用者。要繼續嗎?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"語言偏好設定"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"地區偏好設定"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"輸入語言名稱"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"推薦"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"所有語言"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"搜尋"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 4181697..6554153 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"取得錯誤報告"</string>
     <string name="bugreport_message" msgid="398447048750350456">"這會收集您目前裝置狀態的相關資訊,以便透過電子郵件傳送。從錯誤報告開始建立到準備傳送的這段過程可能需要一點時間,敬請耐心等候。"</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"互動式報告"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"在一般情況下,建議您使用這個選項,以便追蹤報告產生進度,以及輸入更多與問題相關的資訊。系統可能會省略部分較少使用的區段,藉此縮短報告產生時間。"</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"完整報告"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="other">系統將在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後擷取錯誤報告的螢幕畫面。</item>
+      <item quantity="one">系統將在 <xliff:g id="NUMBER_0">%d</xliff:g> 秒後擷取錯誤報告的螢幕畫面。</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"靜音模式"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"音效已關閉"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"音效已開啟"</string>
@@ -1042,15 +1042,15 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
     <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"要與管理員分享錯誤報告嗎?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"您的 IT 管理員要求您提供錯誤報告,協助排解問題"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"您的 IT 管理員要求您提供錯誤報告以便排解問題"</string>
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"接受"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"拒絕"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"正在取得錯誤報告…"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"正在接收錯誤報告…"</string>
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"輕觸即可取消"</string>
     <string name="select_input_method" msgid="8547250819326693584">"變更鍵盤"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"選擇鍵盤"</string>
-    <string name="show_ime" msgid="9157568568695230830">"顯示輸入法"</string>
-    <string name="hardware" msgid="7517821086888990278">"硬體"</string>
+    <string name="show_ime" msgid="2506087537466597099">"有連接的實體鍵盤時保持顯示"</string>
+    <string name="hardware" msgid="194658061510127999">"顯示虛擬鍵盤"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"選取鍵盤配置"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"輕觸即可選取鍵盤配置。"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b></b>"「<xliff:g id="APP">%1$s</xliff:g>」正在嘗試新增使用者,但已達到使用者人數上限。"</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b></b>"「<xliff:g id="APP">%1$s</xliff:g>」正在嘗試新增使用者,但這個裝置上已經有 <xliff:g id="ACCOUNT">%2$s</xliff:g> "<b></b>"這個帳戶。仍要繼續嗎?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b></b>"「<xliff:g id="APP">%1$s</xliff:g>」正在嘗試為 <xliff:g id="ACCOUNT">%2$s</xliff:g> "<b></b>"這個帳戶新增使用者。要繼續嗎?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"語言偏好設定"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"地區偏好設定"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"請輸入語言名稱"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"建議語言"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"所有語言"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"搜尋"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index f257f6c..b6a8039 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -211,15 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Umbiko wephutha"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Thatha umbiko wesiphazamiso"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Lokhu kuzoqoqa ulwazi mayelana nesimo samanje sedivayisi yakho, ukuthumela imilayezo ye-imeyili. Kuzothatha isikhathi esincane kusuka ekuqaleni umbiko wesiphazamiso uze ulungele ukuthunyelwa; sicela ubekezele."</string>
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Umbiko obandakanyayo"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Sebenzisa lokhu ngaphansi kwezimo eziningi. Kukuvumela ukuthi ulandelele ukuqhubeka kombiko uphinde ufake imininingwane engaphezulu mayelana nenkinga. Kungakhipha ezinye izigaba ezisetshenziswe kancane ezithatha isikhathi eside ukuze zibikwe."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Umbiko ogcwele"</string>
+    <!-- no translation found for bugreport_option_full_summary (6687306111256813257) -->
     <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
-    <skip />
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Ithathela umbiko wesiphazamisi isithombe-skrini kumasekhondi angu-<xliff:g id="NUMBER_1">%d</xliff:g>.</item>
+      <item quantity="other">Ithathela umbiko wesiphazamisi isithombe-skrini kumasekhondi angu-<xliff:g id="NUMBER_1">%d</xliff:g>.</item>
+    </plurals>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Imodi ethulile"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Umsindo UVALIWE"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Umsindo UVULIWE"</string>
@@ -1049,8 +1049,8 @@
     <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Thinta ukuze ukhansele"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Shintsha ikhibhodi"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Khetha amakhibhodi"</string>
-    <string name="show_ime" msgid="9157568568695230830">"Bonisa indlela yokufaka"</string>
-    <string name="hardware" msgid="7517821086888990278">"I-Hardware"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Yigcine kusikrini ngenkathi kusebenza ikhibhodi ephathekayo"</string>
+    <string name="hardware" msgid="194658061510127999">"Bonisa ikhibhodi ebonakalayo"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Khetha isendlalelo sekhibhodi"</string>
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Thinta ukuze ukhethe isendlalelo sekhibhodi."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1531,4 +1531,10 @@
     <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" izama ukungeza umsebenzisi omusha, kodwa umkhawulo womsebenzisi ufinyelelwe."</string>
     <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" izama ukungeza umsebenzisi omusha, kodwa i-akhawunti "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" isivele ikhona kule divayisi. Qhubeka noma kunjalo?"</string>
     <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" izama ukungeza umsebenzisi omusha we-akhawunti "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Qhubeka?"</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Okuncamelayo kolimi"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Okuncamelayo kwesifunda"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Thayipha igama lolimi"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Okuphakanyisiwe"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Zonke izilimi"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Sesha"</string>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e0f9eca..713038b 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3412,6 +3412,32 @@
         <attr name="name" />
     </declare-styleable>
 
+    <!-- Use <code>host-nfcf-service</code> as the root tag of the XML resource that
+         describes an {@link android.nfc.cardemulation.HostNfcFService} service, which
+         is referenced from its {@link android.nfc.cardemulation.HostNfcFService#SERVICE_META_DATA}
+         entry. -->
+    <declare-styleable name="HostNfcFService">
+        <!-- Short description of the functionality the service implements. This attribute
+             is mandatory.-->
+        <attr name="description" />
+    </declare-styleable>
+
+    <!-- Specify one or more <code>system-code-filter</code> elements inside a
+         <code>host-nfcf-service</code> element to specify a System Code
+         your service can handle. -->
+    <declare-styleable name="SystemCodeFilter">
+        <!-- The System Code. This attribute is mandatory. -->
+        <attr name="name" />
+    </declare-styleable>
+
+    <!-- Specify one or more <code>nfcid2-filter</code> elements inside a
+         <code>host-nfcf-service</code> element to specify a NFCID2
+         your service can handle. -->
+    <declare-styleable name="Nfcid2Filter">
+        <!-- The NFCID2. This attribute is mandatory. -->
+        <attr name="name" />
+    </declare-styleable>
+
     <declare-styleable name="ActionMenuItemView">
         <attr name="minWidth" />
     </declare-styleable>
@@ -7512,6 +7538,10 @@
         <!-- Flag indicating whether this voice interaction service is capable of being launched
              from the keyguard. -->
         <attr name="supportsLaunchVoiceAssistFromKeyguard" format="boolean" />
+        <!-- Flag indicating whether this voice interaction service can handle local voice
+             interaction requests from an Activity. This flag is new in
+             {@link android.os.Build.VERSION_CODES#N} and not used in previous versions. -->
+        <attr name="supportsLocalInteraction" format="boolean" />
     </declare-styleable>
 
     <!-- Use <code>voice-enrollment-application</code>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 655a5fa..507925b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2462,4 +2462,11 @@
 
     <!-- If true, all guest users created on the device will be ephemeral. -->
     <bool name="config_guestUserEphemeral">false</bool>
+
+    <!-- Enforce strong auth on boot. Setting this to false represents a security risk and should
+         not be ordinarily done. The only case in which this might be permissible is in a car head
+         unit where there are hardware mechanisms to protect the device (physical keys) and not
+         much in the way of user data.
+    -->
+    <bool name="config_strongAuthRequiredOnBoot">true</bool>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index c883b1f..57132ea 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2690,6 +2690,7 @@
     <public type="attr" name="tickMarkTintMode" />
     <public type="attr" name="canPerformGestures" />
     <public type="attr" name="externalService" />
+    <public type="attr" name="supportsLocalInteraction" />
 
     <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 eebdd61..a276854 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -492,17 +492,17 @@
         current device state, to send as an e-mail message.  It will take a little
         time from starting the bug report until it is ready to be sent; please be
         patient.</string>
-    <!-- Title in the bugreport dialog for the interactive workflow. [CHAR LIMIT=20] -->
+    <!-- Title in the bugreport dialog for the interactive workflow. Should fit in one line. [CHAR LIMIT=30] -->
     <string name="bugreport_option_interactive_title">Interactive report</string>
     <!-- Summary in the bugreport dialog for the interactive workflow. [CHAR LIMIT=NONE] -->
     <string name="bugreport_option_interactive_summary">Use this under most circumstances.
         It allows you to track progress of the report and enter more details about the problem.
         It might omit some less-used sections that take a long time to report.</string>
-    <!-- Title in the bugreport dialog for the full workflow. [CHAR LIMIT=20] -->
+    <!-- Title in the bugreport dialog for the full workflow. Should fit in one line. [CHAR LIMIT=30] -->
     <string name="bugreport_option_full_title">Full report</string>
-    <!-- Summary in the bugreport dialog for the full workflow. [CHAR LIMIT=20] -->
-    <string name="bugreport_option_full_summary">Use this option for minimal interference when
-        your device is unresponsive or too slow, or when you need all sections.
+    <!-- Summary in the bugreport dialog for the full workflow. [CHAR LIMIT=NONE] -->
+    <string name="bugreport_option_full_summary">Use this option for minimal system interference when
+        your device is unresponsive or too slow, or when you need all report sections.
         Does not take a screenshot or allow you to enter more details.</string>
     <!--  Toast message informing user in how many seconds a bugreport screenshot will be taken -->
     <plurals name="bugreport_countdown">
@@ -2588,16 +2588,27 @@
     <!-- Text to display when there are no activities found to display in the
          activity chooser. See the "Select an action" title. -->
     <string name="noApplications">No apps can perform this action.</string>
-    <!-- Title of the alert when an application has crashed. -->
-    <string name="aerr_title"></string>
     <!-- Text of the alert that is displayed when an application has crashed. -->
-    <string name="aerr_application">Unfortunately, <xliff:g id="application">%1$s</xliff:g> has stopped.</string>
-    <!-- Text of the alert that is displayed when an application has crashed. -->
-    <string name="aerr_process">Unfortunately, the process <xliff:g id="process">%1$s</xliff:g> has
-        stopped.</string>
-    <!-- Text of the alert that is displayed when an application has crashed. -->
-    <string name="aerr_process_silence">Silence crashes from <xliff:g id="process">%1$s</xliff:g>
-        until reboot.</string>
+    <string name="aerr_application"><xliff:g id="application">%1$s</xliff:g> has stopped</string>
+    <!-- Text of the alert that is displayed when a process has crashed. -->
+    <string name="aerr_process"><xliff:g id="process">%1$s</xliff:g> has
+        stopped</string>
+    <!-- Text of the alert that is displayed when an application has crashed repeatedly. -->
+    <string name="aerr_application_repeated"><xliff:g id="application">%1$s</xliff:g> is repeatedly stopping</string>
+    <!-- Text of the alert that is displayed when a process has crashed repeatedly. -->
+    <string name="aerr_process_repeated"><xliff:g id="process">%1$s</xliff:g> is
+        repeatedly stopping</string>
+    <!-- Button that restarts a crashed application -->
+    <string name="aerr_restart">Restart app</string>
+    <!-- Button that clears cache and restarts a crashed application -->
+    <string name="aerr_reset">Reset and restart app</string>
+    <!-- Button that sends feedback about a crashed application -->
+    <string name="aerr_report">Send feedback</string>
+    <!-- Button that closes a crashed application -->
+    <string name="aerr_close">Close</string>
+    <!-- Button that mutes further crashes of the crashed application-->
+    <string name="aerr_mute">Mute</string>
+
     <!-- Title of the alert when an application is not responding. -->
     <string name="anr_title"></string>
     <!-- Text of the alert that is displayed when an application is not responding. -->
@@ -4164,4 +4175,19 @@
     <!-- Menu item in the locale menu  [CHAR LIMIT=30] -->
     <string name="locale_search_menu">Search</string>
 
+    <!-- Title for dialog displayed when work profile is turned off. [CHAR LIMIT=30] -->
+    <string name="work_mode_off_title">Work mode is OFF</string>
+    <!-- Message displayed in dialog when work profile is turned off. [CHAR LIMIT=NONE] -->
+    <string name="work_mode_off_message">Allow work profile to function, including apps, background sync, and related features.</string>
+    <!-- Title for button to turn on work profile. [CHAR LIMIT=NONE] -->
+    <string name="work_mode_turn_on">Turn on</string>
+    <!-- Title for dialog displayed when a packge is suspended by device admin. [CHAR LIMIT=30] -->
+    <string name="suspended_package_title">%1$s disabled</string>
+    <!-- Message for dialog displayed when a packge is suspended by device admin. [CHAR LIMIT=NONE] -->
+    <string name="suspended_package_message">Disabled by %1$s administrator. Contact them to learn more.</string>
+
+    <!-- Notification title shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] -->
+    <string name="new_sms_notification_title">You have new messages</string>
+    <!-- Notification content shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] -->
+    <string name="new_sms_notification_content">Open SMS app to view</string>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index d5349b2..b660277 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1397,6 +1397,16 @@
         <item name="pointerIconGrabbing">@drawable/pointer_grabbing_large_icon</item>
     </style>
 
+    <!-- @hide -->
+    <style name="aerr_list_item" parent="Widget.Material.Light.TextView">
+        <item name="minHeight">?attr/listPreferredItemHeightSmall</item>
+        <item name="textAppearance">?attr/textAppearanceListItemSmall</item>
+        <item name="textColor">?attr/textColorAlertDialogListItem</item>
+        <item name="gravity">center_vertical</item>
+        <item name="paddingStart">?attr/listPreferredItemPaddingStart</item>
+        <item name="paddingEnd">?attr/listPreferredItemPaddingEnd</item>
+    </style>
+
     <!-- Wifi dialog styles -->
     <!-- @hide -->
     <style name="wifi_item">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a5d0020..81705b4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1763,7 +1763,7 @@
   <java-symbol type="layout" name="launch_warning" />
   <java-symbol type="layout" name="safe_mode" />
   <java-symbol type="layout" name="simple_list_item_2_single_choice" />
-  <java-symbol type="layout" name="app_error_dialog_dont_show_again" />
+  <java-symbol type="layout" name="app_error_dialog" />
   <java-symbol type="plurals" name="wifi_available" />
   <java-symbol type="plurals" name="wifi_available_detailed" />
   <java-symbol type="string" name="accessibility_binding_label" />
@@ -1777,8 +1777,8 @@
   <java-symbol type="string" name="remote_bugreport_progress_notification_message_can_cancel" />
   <java-symbol type="string" name="aerr_application" />
   <java-symbol type="string" name="aerr_process" />
-  <java-symbol type="string" name="aerr_process_silence" />
-  <java-symbol type="string" name="aerr_title" />
+  <java-symbol type="string" name="aerr_application_repeated" />
+  <java-symbol type="string" name="aerr_process_repeated" />
   <java-symbol type="string" name="android_upgrading_fstrim" />
   <java-symbol type="string" name="android_upgrading_apk" />
   <java-symbol type="string" name="android_upgrading_complete" />
@@ -2429,6 +2429,12 @@
   <java-symbol type="id" name="work_widget_app_icon" />
   <java-symbol type="drawable" name="work_widget_mask_view_background" />
 
+  <java-symbol type="id" name="aerr_report" />
+  <java-symbol type="id" name="aerr_reset" />
+  <java-symbol type="id" name="aerr_restart" />
+  <java-symbol type="id" name="aerr_close" />
+  <java-symbol type="id" name="aerr_mute" />
+
   <!-- Framework-private Material.DayNight styles. -->
   <java-symbol type="style" name="Theme.Material.DayNight" />
   <java-symbol type="style" name="Theme.Material.DayNight.DarkActionBar" />
@@ -2485,4 +2491,18 @@
   <java-symbol type="string" name="language_selection_title" />
   <java-symbol type="string" name="search_language_hint" />
 
+  <java-symbol type="layout" name="unlaunchable_app_activity" />
+  <java-symbol type="id" name="unlaunchable_app_title" />
+  <java-symbol type="id" name="unlaunchable_app_message" />
+  <java-symbol type="string" name="work_mode_off_title" />
+  <java-symbol type="string" name="work_mode_off_message" />
+  <java-symbol type="string" name="work_mode_turn_on" />
+  <java-symbol type="string" name="suspended_package_title" />
+  <java-symbol type="string" name="suspended_package_message" />
+
+  <!-- New SMS notification while phone is locked. -->
+  <java-symbol type="string" name="new_sms_notification_title" />
+  <java-symbol type="string" name="new_sms_notification_content" />
+
+  <java-symbol type="bool" name="config_strongAuthRequiredOnBoot" />
 </resources>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 5a08887..cf7978c 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -214,7 +214,7 @@
 
     <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm),
          visual voicemail code for T-Mobile: 122 -->
-    <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327|654)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="122|87902" />
+    <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:567|578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="122|87902" />
 
     <!-- Vietnam -->
     <shortcode country="vn" free="5001" />
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index ee8921e..eb055de 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -32,7 +32,8 @@
     littlemock \
     android-support-test \
     mockito-target \
-    espresso-core
+    espresso-core \
+    ub-uiautomator
 LOCAL_JAVA_LIBRARIES := android.test.runner conscrypt telephony-common org.apache.http.legacy
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
 
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index c0453f8..bfa2b10 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -53,6 +53,7 @@
     <uses-permission android:name="android.permission.DOWNLOAD_CACHE_NON_PURGEABLE" />
     <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
     <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.INJECT_EVENTS" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.READ_LOGS"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
@@ -1294,6 +1295,26 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.print.PrintTestActivity"/>
+
+        <service
+            android:name="android.print.mockservice.MockPrintService"
+            android:permission="android.permission.BIND_PRINT_SERVICE">
+            <intent-filter>
+                <action android:name="android.printservice.PrintService" />
+            </intent-filter>
+            <meta-data
+               android:name="android.printservice"
+               android:resource="@xml/printservice">
+            </meta-data>
+        </service>
+
+        <activity
+            android:name="android.print.mockservice.SettingsActivity"
+            android:permission="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
+            android:exported="true">
+        </activity>
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/core/tests/coretests/res/xml/printservice.xml b/core/tests/coretests/res/xml/printservice.xml
new file mode 100644
index 0000000..abbebda
--- /dev/null
+++ b/core/tests/coretests/res/xml/printservice.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<print-service  xmlns:android="http://schemas.android.com/apk/res/android"
+     android:settingsActivity="android.print.mockservice.SettingsActivity"/>
diff --git a/core/tests/coretests/src/android/content/res/ResourcesLocaleResolutionTest.java b/core/tests/coretests/src/android/content/res/ResourcesLocaleResolutionTest.java
deleted file mode 100644
index 55c0031..0000000
--- a/core/tests/coretests/src/android/content/res/ResourcesLocaleResolutionTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-* Copyright (C) 2015 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package android.content.res;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.DisplayMetrics;
-import android.util.LocaleList;
-
-import java.util.Arrays;
-import java.util.Locale;
-
-public class ResourcesLocaleResolutionTest extends AndroidTestCase {
-    @SmallTest
-    public void testGetResolvedLocale_englishIsAlwaysConsideredSupported() {
-        // First make sure English has no explicit assets other than the default assets
-        final AssetManager assets = getContext().getAssets();
-        final String supportedLocales[] = assets.getNonSystemLocales();
-        for (String languageTag : supportedLocales) {
-            if ("en-XA".equals(languageTag)) {
-                continue;
-            }
-            assertFalse(
-                    "supported locales: " + Arrays.toString(supportedLocales),
-                    "en".equals(Locale.forLanguageTag(languageTag).getLanguage()));
-        }
-
-        final DisplayMetrics dm = new DisplayMetrics();
-        dm.setToDefaults();
-        final Configuration cfg = new Configuration();
-        cfg.setToDefaults();
-        // Avestan and English have no assets, but Persian does.
-        cfg.setLocales(LocaleList.forLanguageTags("ae,en,fa"));
-        Resources res = new Resources(assets, dm, cfg);
-        // We should get English, because it is always considered supported.
-        assertEquals("en", res.getResolvedLocale().toLanguageTag());
-    }
-}
-
diff --git a/core/tests/coretests/src/android/print/BasePrintTest.java b/core/tests/coretests/src/android/print/BasePrintTest.java
new file mode 100644
index 0000000..19ce44a
--- /dev/null
+++ b/core/tests/coretests/src/android/print/BasePrintTest.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.print;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.print.PrintAttributes;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintManager;
+import android.print.PrinterId;
+import android.print.mockservice.PrintServiceCallbacks;
+import android.print.mockservice.PrinterDiscoverySessionCallbacks;
+import android.print.mockservice.StubbablePrinterDiscoverySession;
+import android.printservice.CustomPrinterIconCallback;
+import android.printservice.PrintJob;
+import android.printservice.PrintService;
+import android.test.InstrumentationTestCase;
+import android.util.DisplayMetrics;
+import android.util.LocaleList;
+
+import org.mockito.stubbing.Answer;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * This is the base class for print tests.
+ */
+public abstract class BasePrintTest extends InstrumentationTestCase {
+
+    private static final long OPERATION_TIMEOUT = 30000;
+    private static final String PRINT_SPOOLER_PACKAGE_NAME = "com.android.printspooler";
+    private static final String PM_CLEAR_SUCCESS_OUTPUT = "Success";
+    private static final String COMMAND_LIST_ENABLED_IME_COMPONENTS = "ime list -s";
+    private static final String COMMAND_PREFIX_ENABLE_IME = "ime enable ";
+    private static final String COMMAND_PREFIX_DISABLE_IME = "ime disable ";
+    private static final int CURRENT_USER_ID = -2; // Mirrors UserHandle.USER_CURRENT
+
+    private PrintTestActivity mActivity;
+    private android.print.PrintJob mPrintJob;
+
+    private LocaleList mOldLocale;
+
+    private CallCounter mStartCallCounter;
+    private CallCounter mStartSessionCallCounter;
+
+    private String[] mEnabledImes;
+
+    private String[] getEnabledImes() throws IOException {
+        List<String> imeList = new ArrayList<>();
+
+        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                .executeShellCommand(COMMAND_LIST_ENABLED_IME_COMPONENTS);
+        try (BufferedReader reader = new BufferedReader(
+                new InputStreamReader(new FileInputStream(pfd.getFileDescriptor())))) {
+
+            String line;
+            while ((line = reader.readLine()) != null) {
+                imeList.add(line);
+            }
+        }
+
+        String[] imeArray = new String[imeList.size()];
+        imeList.toArray(imeArray);
+
+        return imeArray;
+    }
+
+    private void disableImes() throws Exception {
+        mEnabledImes = getEnabledImes();
+        for (String ime : mEnabledImes) {
+            String disableImeCommand = COMMAND_PREFIX_DISABLE_IME + ime;
+            runShellCommand(getInstrumentation(), disableImeCommand);
+        }
+    }
+
+    private void enableImes() throws Exception {
+        for (String ime : mEnabledImes) {
+            String enableImeCommand = COMMAND_PREFIX_ENABLE_IME + ime;
+            runShellCommand(getInstrumentation(), enableImeCommand);
+        }
+        mEnabledImes = null;
+    }
+
+    @Override
+    protected void runTest() throws Throwable {
+        // Do nothing if the device does not support printing.
+        if (supportsPrinting()) {
+            super.runTest();
+        }
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        // Make sure we start with a clean slate.
+        clearPrintSpoolerData();
+        disableImes();
+
+        // Workaround for dexmaker bug: https://code.google.com/p/dexmaker/issues/detail?id=2
+        // Dexmaker is used by mockito.
+        System.setProperty("dexmaker.dexcache", getInstrumentation()
+                .getTargetContext().getCacheDir().getPath());
+
+        // Set to US locale.
+        Resources resources = getInstrumentation().getTargetContext().getResources();
+        Configuration oldConfiguration = resources.getConfiguration();
+        if (!oldConfiguration.getLocales().getPrimary().equals(Locale.US)) {
+            mOldLocale = oldConfiguration.getLocales();
+            DisplayMetrics displayMetrics = resources.getDisplayMetrics();
+            Configuration newConfiguration = new Configuration(oldConfiguration);
+            newConfiguration.setLocale(Locale.US);
+            resources.updateConfiguration(newConfiguration, displayMetrics);
+        }
+
+        // Initialize the latches.
+        mStartCallCounter = new CallCounter();
+        mStartSessionCallCounter = new CallCounter();
+
+        // Create the activity for the right locale.
+        createActivity();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
+        // Done with the activity.
+        getActivity().finish();
+        enableImes();
+
+        // Restore the locale if needed.
+        if (mOldLocale != null) {
+            Resources resources = getInstrumentation().getTargetContext().getResources();
+            DisplayMetrics displayMetrics = resources.getDisplayMetrics();
+            Configuration newConfiguration = new Configuration(resources.getConfiguration());
+            newConfiguration.setLocales(mOldLocale);
+            mOldLocale = null;
+            resources.updateConfiguration(newConfiguration, displayMetrics);
+        }
+
+        // Make sure the spooler is cleaned, this also un-approves all services
+        clearPrintSpoolerData();
+
+        super.tearDown();
+    }
+
+    protected android.print.PrintJob print(@NonNull final PrintDocumentAdapter adapter,
+            final PrintAttributes attributes) {
+        // Initiate printing as if coming from the app.
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                PrintManager printManager = (PrintManager) getActivity()
+                        .getSystemService(Context.PRINT_SERVICE);
+                mPrintJob = printManager.print("Print job", adapter, attributes);
+            }
+        });
+
+        return mPrintJob;
+    }
+
+    protected void onStartCalled() {
+        mStartCallCounter.call();
+    }
+
+    protected void onPrinterDiscoverySessionStartCalled() {
+        mStartSessionCallCounter.call();
+    }
+
+    protected void waitForPrinterDiscoverySessionStartCallbackCalled() {
+        waitForCallbackCallCount(mStartSessionCallCounter, 1,
+                "Did not get expected call to onStartPrinterDiscoverySession.");
+    }
+
+    protected void waitForStartAdapterCallbackCalled() {
+        waitForCallbackCallCount(mStartCallCounter, 1, "Did not get expected call to start.");
+    }
+
+    private void waitForCallbackCallCount(CallCounter counter, int count, String message) {
+        try {
+            counter.waitForCount(count, OPERATION_TIMEOUT);
+        } catch (TimeoutException te) {
+            fail(message);
+        }
+    }
+
+    protected PrintTestActivity getActivity() {
+        return mActivity;
+    }
+
+    protected void createActivity() {
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                PrintTestActivity.class, null);
+    }
+
+    public static String runShellCommand(Instrumentation instrumentation, String cmd)
+            throws IOException {
+        ParcelFileDescriptor pfd = instrumentation.getUiAutomation().executeShellCommand(cmd);
+        byte[] buf = new byte[512];
+        int bytesRead;
+        FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+        StringBuffer stdout = new StringBuffer();
+        while ((bytesRead = fis.read(buf)) != -1) {
+            stdout.append(new String(buf, 0, bytesRead));
+        }
+        fis.close();
+        return stdout.toString();
+    }
+
+    protected void clearPrintSpoolerData() throws Exception {
+        assertTrue("failed to clear print spooler data",
+                runShellCommand(getInstrumentation(), String.format(
+                        "pm clear --user %d %s", CURRENT_USER_ID, PRINT_SPOOLER_PACKAGE_NAME))
+                                .contains(PM_CLEAR_SUCCESS_OUTPUT));
+    }
+
+    @SuppressWarnings("unchecked")
+    protected PrinterDiscoverySessionCallbacks createMockPrinterDiscoverySessionCallbacks(
+            Answer<Void> onStartPrinterDiscovery, Answer<Void> onStopPrinterDiscovery,
+            Answer<Void> onValidatePrinters, Answer<Void> onStartPrinterStateTracking,
+            Answer<Void> onRequestCustomPrinterIcon, Answer<Void> onStopPrinterStateTracking,
+            Answer<Void> onDestroy) {
+        PrinterDiscoverySessionCallbacks callbacks = mock(PrinterDiscoverySessionCallbacks.class);
+
+        doCallRealMethod().when(callbacks).setSession(any(StubbablePrinterDiscoverySession.class));
+        when(callbacks.getSession()).thenCallRealMethod();
+
+        if (onStartPrinterDiscovery != null) {
+            doAnswer(onStartPrinterDiscovery).when(callbacks).onStartPrinterDiscovery(
+                    any(List.class));
+        }
+        if (onStopPrinterDiscovery != null) {
+            doAnswer(onStopPrinterDiscovery).when(callbacks).onStopPrinterDiscovery();
+        }
+        if (onValidatePrinters != null) {
+            doAnswer(onValidatePrinters).when(callbacks).onValidatePrinters(
+                    any(List.class));
+        }
+        if (onStartPrinterStateTracking != null) {
+            doAnswer(onStartPrinterStateTracking).when(callbacks).onStartPrinterStateTracking(
+                    any(PrinterId.class));
+        }
+        if (onRequestCustomPrinterIcon != null) {
+            doAnswer(onRequestCustomPrinterIcon).when(callbacks).onRequestCustomPrinterIcon(
+                    any(PrinterId.class), any(CustomPrinterIconCallback.class));
+        }
+        if (onStopPrinterStateTracking != null) {
+            doAnswer(onStopPrinterStateTracking).when(callbacks).onStopPrinterStateTracking(
+                    any(PrinterId.class));
+        }
+        if (onDestroy != null) {
+            doAnswer(onDestroy).when(callbacks).onDestroy();
+        }
+
+        return callbacks;
+    }
+
+    protected PrintServiceCallbacks createMockPrintServiceCallbacks(
+            Answer<PrinterDiscoverySessionCallbacks> onCreatePrinterDiscoverySessionCallbacks,
+            Answer<Void> onPrintJobQueued, Answer<Void> onRequestCancelPrintJob) {
+        final PrintServiceCallbacks service = mock(PrintServiceCallbacks.class);
+
+        doCallRealMethod().when(service).setService(any(PrintService.class));
+        when(service.getService()).thenCallRealMethod();
+
+        if (onCreatePrinterDiscoverySessionCallbacks != null) {
+            doAnswer(onCreatePrinterDiscoverySessionCallbacks).when(service)
+                    .onCreatePrinterDiscoverySessionCallbacks();
+        }
+        if (onPrintJobQueued != null) {
+            doAnswer(onPrintJobQueued).when(service).onPrintJobQueued(any(PrintJob.class));
+        }
+        if (onRequestCancelPrintJob != null) {
+            doAnswer(onRequestCancelPrintJob).when(service).onRequestCancelPrintJob(
+                    any(PrintJob.class));
+        }
+
+        return service;
+    }
+
+    protected final class CallCounter {
+        private final Object mLock = new Object();
+
+        private int mCallCount;
+
+        public void call() {
+            synchronized (mLock) {
+                mCallCount++;
+                mLock.notifyAll();
+            }
+        }
+
+        public int getCallCount() {
+            synchronized (mLock) {
+                return mCallCount;
+            }
+        }
+
+        public void waitForCount(int count, long timeoutMillis) throws TimeoutException {
+            synchronized (mLock) {
+                final long startTimeMillis = SystemClock.uptimeMillis();
+                while (mCallCount < count) {
+                    try {
+                        final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
+                        final long remainingTimeMillis = timeoutMillis - elapsedTimeMillis;
+                        if (remainingTimeMillis <= 0) {
+                            throw new TimeoutException();
+                        }
+                        mLock.wait(timeoutMillis);
+                    } catch (InterruptedException ie) {
+                        /* ignore */
+                    }
+                }
+            }
+        }
+    }
+
+    protected boolean supportsPrinting() {
+        return getInstrumentation().getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_PRINTING);
+    }
+}
diff --git a/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java
new file mode 100644
index 0000000..5179b42
--- /dev/null
+++ b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java
@@ -0,0 +1,669 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.print;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.print.IPrintDocumentAdapter;
+import android.print.IPrintJobStateChangeListener;
+import android.print.IPrintManager;
+import android.print.IPrinterDiscoveryObserver;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintJob;
+import android.print.PrintJobId;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterDiscoverySession;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.printservice.PrintServiceInfo;
+
+import android.print.mockservice.MockPrintService;
+import android.print.mockservice.PrintServiceCallbacks;
+import android.print.mockservice.PrinterDiscoverySessionCallbacks;
+import android.print.mockservice.StubbablePrinterDiscoverySession;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * tests feeding all possible parameters to the IPrintManager Binder.
+ */
+public class IPrintManagerParametersTest extends BasePrintTest {
+
+    private final int BAD_APP_ID = 0xffffffff;
+
+    private final int mAppId;
+    private final int mUserId;
+    private final PrintJobId mBadPrintJobId;
+
+    private PrintJob mGoodPrintJob;
+    private PrinterId mBadPrinterId;
+    private PrinterId mGoodPrinterId;
+    private ComponentName mGoodComponentName;
+    private ComponentName mBadComponentName;
+
+    private IPrintManager mIPrintManager;
+
+    /**
+     * Create a new IPrintManagerParametersTest and setup basic fields.
+     */
+    public IPrintManagerParametersTest() {
+        super();
+
+        mAppId = UserHandle.getAppId(Process.myUid());
+        mUserId = UserHandle.myUserId();
+        mBadPrintJobId = new PrintJobId();
+        mBadComponentName = new ComponentName("bad", "bad");
+    }
+
+    /**
+     * Create a mock PrintDocumentAdapter.
+     *
+     * @return The adapter
+     */
+    private @NonNull PrintDocumentAdapter createMockAdapter() {
+        return new PrintDocumentAdapter() {
+            @Override
+            public void onStart() {
+                onStartCalled();
+            }
+
+            @Override
+            public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
+                    CancellationSignal cancellationSignal, LayoutResultCallback callback,
+                    Bundle extras) {
+            }
+
+            @Override
+            public void onWrite(PageRange[] pages, ParcelFileDescriptor destination,
+                    CancellationSignal cancellationSignal, WriteResultCallback callback) {
+            }
+        };
+    }
+
+    /**
+     * Create mock print service callbacks.
+     *
+     * @return the callbacks
+     */
+    private PrintServiceCallbacks createMockCallbacks() {
+        return createMockPrintServiceCallbacks(
+                new Answer<PrinterDiscoverySessionCallbacks>() {
+                    @Override
+                    public PrinterDiscoverySessionCallbacks answer(InvocationOnMock invocation) {
+                        return createMockPrinterDiscoverySessionCallbacks(new Answer<Void>() {
+                            @Override
+                            public Void answer(InvocationOnMock invocation) {
+                                // Get the session.
+                                StubbablePrinterDiscoverySession session =
+                                        ((PrinterDiscoverySessionCallbacks) invocation
+                                        .getMock()).getSession();
+
+                                if (session.getPrinters().isEmpty()) {
+                                    final String PRINTER_NAME = "good printer";
+                                    List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+
+                                    // Add the printer.
+                                    mGoodPrinterId = session.getService()
+                                            .generatePrinterId(PRINTER_NAME);
+
+                                    PrinterCapabilitiesInfo capabilities =
+                                            new PrinterCapabilitiesInfo.Builder(mGoodPrinterId)
+                                                    .setMinMargins(
+                                                            new Margins(200, 200, 200, 200))
+                                                    .addMediaSize(MediaSize.ISO_A4, true)
+                                                    .addResolution(new Resolution("300x300",
+                                                            "300x300", 300, 300),
+                                                            true)
+                                                    .setColorModes(
+                                                            PrintAttributes.COLOR_MODE_COLOR,
+                                                            PrintAttributes.COLOR_MODE_COLOR)
+                                                    .build();
+
+                                    PrinterInfo printer = new PrinterInfo.Builder(
+                                            mGoodPrinterId,
+                                            PRINTER_NAME,
+                                            PrinterInfo.STATUS_IDLE)
+                                                    .setCapabilities(capabilities)
+                                                    .build();
+                                    printers.add(printer);
+
+                                    session.addPrinters(printers);
+                                }
+                                onPrinterDiscoverySessionStartCalled();
+                                return null;
+                            }
+                        }, null, null, null, null, null, null);
+                    }
+                },
+                null, null);
+    }
+
+    /**
+     * Create a IPrintJobStateChangeListener object.
+     *
+     * @return the object
+     * @throws Exception if the object could not be created.
+     */
+    private IPrintJobStateChangeListener createMockIPrintJobStateChangeListener() throws Exception {
+        return new PrintManager.PrintJobStateChangeListenerWrapper(null,
+                new Handler(Looper.getMainLooper()));
+    }
+
+    /**
+     * Create a IPrinterDiscoveryObserver object.
+     *
+     * @return the object
+     * @throws Exception if the object could not be created.
+     */
+    private IPrinterDiscoveryObserver createMockIPrinterDiscoveryObserver() throws Exception {
+        return new PrinterDiscoverySession.PrinterDiscoveryObserver(null);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        MockPrintService.setCallbacks(createMockCallbacks());
+
+        mGoodComponentName = getActivity().getComponentName();
+
+        mGoodPrintJob = print(createMockAdapter(), null);
+
+        mIPrintManager = IPrintManager.Stub
+                .asInterface(ServiceManager.getService(Context.PRINT_SERVICE));
+
+        // Generate dummy printerId which is a valid PrinterId object, but does not correspond to a
+        // printer
+        mBadPrinterId = new PrinterId(mGoodComponentName, "dummy printer");
+
+        // Wait for PrintActivity to be ready
+        waitForStartAdapterCallbackCalled();
+
+        // Wait for printer discovery session to be ready
+        waitForPrinterDiscoverySessionStartCallbackCalled();
+    }
+
+    /**
+     * {@link Runnable} that can throw and {@link Exception}
+     */
+    private interface Invokable {
+        /**
+         * Execute the {@link Invokable}
+         *
+         * @throws Exception
+         */
+        public void run() throws Exception;
+    }
+
+    /**
+     * Assert that the invokable throws an expectedException
+     *
+     * @param invokable The {@link Invokable} to run
+     * @param expectedClass The {@link Exception} that is supposed to be thrown
+     */
+    public void assertException(Invokable invokable, Class<? extends Exception> expectedClass)
+            throws Exception {
+        try {
+            invokable.run();
+        } catch (Exception e) {
+            if (e.getClass().isAssignableFrom(expectedClass)) {
+                return;
+            } else {
+                throw new AssertionError("Expected: " + expectedClass.getName() + ", got: "
+                                + e.getClass().getName());
+            }
+        }
+
+        throw new AssertionError("No exception thrown");
+    }
+
+    /**
+     * test IPrintManager.getPrintJobInfo
+     */
+    public void testGetPrintJobInfo() throws Exception {
+        assertEquals(mGoodPrintJob.getId(), mIPrintManager.getPrintJobInfo(mGoodPrintJob.getId(),
+                        mAppId, mUserId).getId());
+        assertEquals(null, mIPrintManager.getPrintJobInfo(mBadPrintJobId, mAppId, mUserId));
+        assertEquals(null, mIPrintManager.getPrintJobInfo(null, mAppId, mUserId));
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.getPrintJobInfo(mGoodPrintJob.getId(), BAD_APP_ID, mUserId);
+            }
+        }, SecurityException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.getPrintJobInfos
+     */
+    public void testGetPrintJobInfos() throws Exception {
+        List<PrintJobInfo> infos = mIPrintManager.getPrintJobInfos(mAppId, mUserId);
+
+        boolean foundPrintJob = false;
+        for (PrintJobInfo info : infos) {
+            if (info.getId().equals(mGoodPrintJob.getId())) {
+                assertEquals(PrintJobInfo.STATE_CREATED, info.getState());
+                foundPrintJob = true;
+            }
+        }
+        assertTrue(foundPrintJob);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.getPrintJobInfos(BAD_APP_ID, mUserId);
+            }
+        }, SecurityException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.print
+     */
+    public void testPrint() throws Exception {
+        final String name = "dummy print job";
+
+        final IPrintDocumentAdapter adapter = new PrintManager
+                .PrintDocumentAdapterDelegate(getActivity(), createMockAdapter());
+
+        // Valid parameters are tested in setUp()
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.print(null, adapter, null, mGoodComponentName.getPackageName(),
+                        mAppId, mUserId);
+            }
+        }, IllegalArgumentException.class);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.print(name, null, null, mGoodComponentName.getPackageName(),
+                        mAppId, mUserId);
+            }
+        }, NullPointerException.class);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.print(name, adapter, null, null, mAppId, mUserId);
+            }
+        }, IllegalArgumentException.class);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.print(name, adapter, null, mBadComponentName.getPackageName(),
+                        mAppId, mUserId);
+            }
+        }, IllegalArgumentException.class);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.print(name, adapter, null, mGoodComponentName.getPackageName(),
+                        BAD_APP_ID, mUserId);
+            }
+        }, SecurityException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.cancelPrintJob
+     */
+    public void testCancelPrintJob() throws Exception {
+        // Invalid print jobs IDs do not produce an exception
+        mIPrintManager.cancelPrintJob(mBadPrintJobId, mAppId, mUserId);
+        mIPrintManager.cancelPrintJob(null, mAppId, mUserId);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.cancelPrintJob(mGoodPrintJob.getId(), BAD_APP_ID, mUserId);
+            }
+        }, SecurityException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+
+        // Must be last as otherwise mGoodPrintJob will not be good anymore
+        mIPrintManager.cancelPrintJob(mGoodPrintJob.getId(), mAppId, mUserId);
+    }
+
+    /**
+     * test IPrintManager.restartPrintJob
+     */
+    public void testRestartPrintJob() throws Exception {
+        mIPrintManager.restartPrintJob(mGoodPrintJob.getId(), mAppId, mUserId);
+
+        // Invalid print jobs IDs do not produce an exception
+        mIPrintManager.restartPrintJob(mBadPrintJobId, mAppId, mUserId);
+        mIPrintManager.restartPrintJob(null, mAppId, mUserId);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.restartPrintJob(mGoodPrintJob.getId(), BAD_APP_ID, mUserId);
+            }
+        }, SecurityException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.addPrintJobStateChangeListener
+     */
+    public void testAddPrintJobStateChangeListener() throws Exception {
+        final IPrintJobStateChangeListener listener = createMockIPrintJobStateChangeListener();
+
+        mIPrintManager.addPrintJobStateChangeListener(listener, mAppId, mUserId);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.addPrintJobStateChangeListener(null, mAppId, mUserId);
+            }
+        }, NullPointerException.class);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.addPrintJobStateChangeListener(listener, BAD_APP_ID, mUserId);
+            }
+        }, SecurityException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.removePrintJobStateChangeListener
+     */
+    public void testRemovePrintJobStateChangeListener() throws Exception {
+        final IPrintJobStateChangeListener listener = createMockIPrintJobStateChangeListener();
+
+        mIPrintManager.addPrintJobStateChangeListener(listener, mAppId, mUserId);
+        mIPrintManager.removePrintJobStateChangeListener(listener, mUserId);
+
+        // Removing unknown listeners is a no-op
+        mIPrintManager.removePrintJobStateChangeListener(listener, mUserId);
+
+        mIPrintManager.addPrintJobStateChangeListener(listener, mAppId, mUserId);
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.removePrintJobStateChangeListener(null, mUserId);
+            }
+        }, NullPointerException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.getInstalledPrintServices
+     */
+    public void testGetInstalledPrintServices() throws Exception {
+        List<PrintServiceInfo> printServices = mIPrintManager.getInstalledPrintServices(mUserId);
+        assertTrue(printServices.size() >= 2);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.getEnabledPrintServices
+     */
+    public void testGetEnabledPrintServices() throws Exception {
+        List<PrintServiceInfo> printServices = mIPrintManager.getEnabledPrintServices(mUserId);
+        assertTrue(printServices.size() >= 2);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.createPrinterDiscoverySession
+     */
+    public void testCreatePrinterDiscoverySession() throws Exception {
+        final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
+
+        mIPrintManager.createPrinterDiscoverySession(listener, mUserId);
+
+        try {
+            assertException(new Invokable() {
+                @Override
+                public void run() throws Exception {
+                    mIPrintManager.createPrinterDiscoverySession(null, mUserId);
+                }
+            }, NullPointerException.class);
+
+            // Cannot test bad user Id as these tests are allowed to call across users
+        } finally {
+            // Remove discovery session so that the next test create a new one. Usually a leaked
+            // session is removed on the next call from the print service. But in this case we want
+            // to force a new call to onPrinterDiscoverySessionStart in the next test.
+            mIPrintManager.destroyPrinterDiscoverySession(listener, mUserId);
+        }
+    }
+
+    /**
+     * test IPrintManager.startPrinterDiscovery
+     */
+    public void testStartPrinterDiscovery() throws Exception {
+        final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
+        final List<PrinterId> goodPrinters = new ArrayList<>();
+        goodPrinters.add(mGoodPrinterId);
+
+        final List<PrinterId> badPrinters = new ArrayList<>();
+        badPrinters.add(mBadPrinterId);
+
+        final List<PrinterId> emptyPrinters = new ArrayList<>();
+
+        final List<PrinterId> nullPrinters = new ArrayList<>();
+        nullPrinters.add(null);
+
+        mIPrintManager.startPrinterDiscovery(listener, goodPrinters, mUserId);
+
+        // Bad or no printers do no cause exceptions
+        mIPrintManager.startPrinterDiscovery(listener, badPrinters, mUserId);
+        mIPrintManager.startPrinterDiscovery(listener, emptyPrinters, mUserId);
+        mIPrintManager.startPrinterDiscovery(listener, null, mUserId);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.startPrinterDiscovery(listener, nullPrinters, mUserId);
+            }
+        }, NullPointerException.class);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.startPrinterDiscovery(null, goodPrinters, mUserId);
+            }
+        }, NullPointerException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.stopPrinterDiscovery
+     */
+    public void testStopPrinterDiscovery() throws Exception {
+        final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
+
+        mIPrintManager.startPrinterDiscovery(listener, null, mUserId);
+        mIPrintManager.stopPrinterDiscovery(listener, mUserId);
+
+        // Stopping an already stopped session is a no-op
+        mIPrintManager.stopPrinterDiscovery(listener, mUserId);
+
+        mIPrintManager.startPrinterDiscovery(listener, null, mUserId);
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.stopPrinterDiscovery(null, mUserId);
+            }
+        }, NullPointerException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.validatePrinters
+     */
+    public void testValidatePrinters() throws Exception {
+        final List<PrinterId> goodPrinters = new ArrayList<>();
+        goodPrinters.add(mGoodPrinterId);
+
+        final List<PrinterId> badPrinters = new ArrayList<>();
+        badPrinters.add(mBadPrinterId);
+
+        final List<PrinterId> emptyPrinters = new ArrayList<>();
+
+        final List<PrinterId> nullPrinters = new ArrayList<>();
+        nullPrinters.add(null);
+
+        mIPrintManager.validatePrinters(goodPrinters, mUserId);
+
+        // Bad or empty list of printers do no cause exceptions
+        mIPrintManager.validatePrinters(badPrinters, mUserId);
+        mIPrintManager.validatePrinters(emptyPrinters, mUserId);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.validatePrinters(null, mUserId);
+            }
+        }, NullPointerException.class);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.validatePrinters(nullPrinters, mUserId);
+            }
+        }, NullPointerException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.startPrinterStateTracking
+     */
+    public void testStartPrinterStateTracking() throws Exception {
+        mIPrintManager.startPrinterStateTracking(mGoodPrinterId, mUserId);
+
+        // Bad printers do no cause exceptions
+        mIPrintManager.startPrinterStateTracking(mBadPrinterId, mUserId);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.startPrinterStateTracking(null, mUserId);
+            }
+        }, NullPointerException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.getCustomPrinterIcon
+     */
+    public void testGetCustomPrinterIcon() throws Exception {
+        mIPrintManager.getCustomPrinterIcon(mGoodPrinterId, mUserId);
+
+        // Bad printers do no cause exceptions
+        mIPrintManager.getCustomPrinterIcon(mBadPrinterId, mUserId);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.getCustomPrinterIcon(null, mUserId);
+            }
+        }, NullPointerException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.stopPrinterStateTracking
+     */
+    public void testStopPrinterStateTracking() throws Exception {
+        mIPrintManager.startPrinterStateTracking(mGoodPrinterId, mUserId);
+        mIPrintManager.stopPrinterStateTracking(mGoodPrinterId, mUserId);
+
+        // Stop to track a non-tracked printer is a no-op
+        mIPrintManager.stopPrinterStateTracking(mGoodPrinterId, mUserId);
+
+        // Bad printers do no cause exceptions
+        mIPrintManager.startPrinterStateTracking(mBadPrinterId, mUserId);
+        mIPrintManager.stopPrinterStateTracking(mBadPrinterId, mUserId);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.stopPrinterStateTracking(null, mUserId);
+            }
+        }, NullPointerException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+
+    /**
+     * test IPrintManager.destroyPrinterDiscoverySession
+     */
+    public void testDestroyPrinterDiscoverySession() throws Exception {
+        final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
+
+        mIPrintManager.createPrinterDiscoverySession(listener, mUserId);
+        mIPrintManager.destroyPrinterDiscoverySession(listener, mUserId);
+
+        // Destroying already destroyed session is a no-op
+        mIPrintManager.destroyPrinterDiscoverySession(listener, mUserId);
+
+        assertException(new Invokable() {
+            @Override
+            public void run() throws Exception {
+                mIPrintManager.destroyPrinterDiscoverySession(null, mUserId);
+            }
+        }, NullPointerException.class);
+
+        // Cannot test bad user Id as these tests are allowed to call across users
+    }
+}
diff --git a/core/tests/coretests/src/android/print/PrintTestActivity.java b/core/tests/coretests/src/android/print/PrintTestActivity.java
new file mode 100644
index 0000000..86074a6
--- /dev/null
+++ b/core/tests/coretests/src/android/print/PrintTestActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.print;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public class PrintTestActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+    }
+}
diff --git a/core/tests/coretests/src/android/print/mockservice/MockPrintService.java b/core/tests/coretests/src/android/print/mockservice/MockPrintService.java
new file mode 100644
index 0000000..9c11c22
--- /dev/null
+++ b/core/tests/coretests/src/android/print/mockservice/MockPrintService.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.print.mockservice;
+
+public class MockPrintService extends StubbablePrintService {
+
+    private static final Object sLock = new Object();
+
+    private static PrintServiceCallbacks sCallbacks;
+
+    public static void setCallbacks(PrintServiceCallbacks callbacks) {
+        synchronized (sLock) {
+            sCallbacks = callbacks;
+        }
+    }
+
+    @Override
+    protected PrintServiceCallbacks getCallbacks() {
+        synchronized (sLock) {
+            if (sCallbacks != null) {
+                sCallbacks.setService(this);
+            }
+            return sCallbacks;
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/print/mockservice/PrintServiceCallbacks.java b/core/tests/coretests/src/android/print/mockservice/PrintServiceCallbacks.java
new file mode 100644
index 0000000..4e89207
--- /dev/null
+++ b/core/tests/coretests/src/android/print/mockservice/PrintServiceCallbacks.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.print.mockservice;
+
+import android.printservice.PrintJob;
+import android.printservice.PrintService;
+
+public abstract class PrintServiceCallbacks {
+
+    private PrintService mService;
+
+    public PrintService getService() {
+        return mService;
+    }
+
+    public void setService(PrintService service) {
+        mService = service;
+    }
+
+    public abstract PrinterDiscoverySessionCallbacks onCreatePrinterDiscoverySessionCallbacks();
+
+    public abstract void onRequestCancelPrintJob(PrintJob printJob);
+
+    public abstract void onPrintJobQueued(PrintJob printJob);
+}
diff --git a/core/tests/coretests/src/android/print/mockservice/PrinterDiscoverySessionCallbacks.java b/core/tests/coretests/src/android/print/mockservice/PrinterDiscoverySessionCallbacks.java
new file mode 100644
index 0000000..26b7cae
--- /dev/null
+++ b/core/tests/coretests/src/android/print/mockservice/PrinterDiscoverySessionCallbacks.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.print.mockservice;
+
+import android.print.PrinterId;
+import android.printservice.CustomPrinterIconCallback;
+
+import java.util.List;
+
+public abstract class PrinterDiscoverySessionCallbacks {
+
+    private StubbablePrinterDiscoverySession mSession;
+
+    public void setSession(StubbablePrinterDiscoverySession session) {
+        mSession = session;
+    }
+
+    public StubbablePrinterDiscoverySession getSession() {
+        return mSession;
+    }
+
+    public abstract void onStartPrinterDiscovery(List<PrinterId> priorityList);
+
+    public abstract void onStopPrinterDiscovery();
+
+    public abstract void onValidatePrinters(List<PrinterId> printerIds);
+
+    public abstract void onStartPrinterStateTracking(PrinterId printerId);
+
+    public abstract void onRequestCustomPrinterIcon(PrinterId printerId,
+            CustomPrinterIconCallback callback);
+
+    public abstract void onStopPrinterStateTracking(PrinterId printerId);
+
+    public abstract void onDestroy();
+}
diff --git a/core/tests/coretests/src/android/print/mockservice/SettingsActivity.java b/core/tests/coretests/src/android/print/mockservice/SettingsActivity.java
new file mode 100644
index 0000000..fb76e67
--- /dev/null
+++ b/core/tests/coretests/src/android/print/mockservice/SettingsActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.print.mockservice;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class SettingsActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/core/tests/coretests/src/android/print/mockservice/StubbablePrintService.java b/core/tests/coretests/src/android/print/mockservice/StubbablePrintService.java
new file mode 100644
index 0000000..b58b2735
--- /dev/null
+++ b/core/tests/coretests/src/android/print/mockservice/StubbablePrintService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.print.mockservice;
+
+import android.printservice.PrintJob;
+import android.printservice.PrintService;
+import android.printservice.PrinterDiscoverySession;
+
+public abstract class StubbablePrintService extends PrintService {
+
+    @Override
+    public PrinterDiscoverySession onCreatePrinterDiscoverySession() {
+        PrintServiceCallbacks callbacks = getCallbacks();
+        if (callbacks != null) {
+            return new StubbablePrinterDiscoverySession(this,
+                    getCallbacks().onCreatePrinterDiscoverySessionCallbacks());
+        }
+        return null;
+    }
+
+    @Override
+    public void onRequestCancelPrintJob(PrintJob printJob) {
+        PrintServiceCallbacks callbacks = getCallbacks();
+        if (callbacks != null) {
+            callbacks.onRequestCancelPrintJob(printJob);
+        }
+    }
+
+    @Override
+    public void onPrintJobQueued(PrintJob printJob) {
+        PrintServiceCallbacks callbacks = getCallbacks();
+        if (callbacks != null) {
+            callbacks.onPrintJobQueued(printJob);
+        }
+    }
+
+    protected abstract PrintServiceCallbacks getCallbacks();
+}
diff --git a/core/tests/coretests/src/android/print/mockservice/StubbablePrinterDiscoverySession.java b/core/tests/coretests/src/android/print/mockservice/StubbablePrinterDiscoverySession.java
new file mode 100644
index 0000000..04683f2
--- /dev/null
+++ b/core/tests/coretests/src/android/print/mockservice/StubbablePrinterDiscoverySession.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.print.mockservice;
+
+import android.print.PrinterId;
+import android.printservice.CustomPrinterIconCallback;
+import android.printservice.PrintService;
+import android.printservice.PrinterDiscoverySession;
+
+import java.util.List;
+
+public class StubbablePrinterDiscoverySession extends PrinterDiscoverySession {
+    private final PrintService mService;
+    private final PrinterDiscoverySessionCallbacks mCallbacks;
+
+    public StubbablePrinterDiscoverySession(PrintService service,
+            PrinterDiscoverySessionCallbacks callbacks) {
+        mService = service;
+        mCallbacks = callbacks;
+        if (mCallbacks != null) {
+            mCallbacks.setSession(this);
+        }
+    }
+
+    public PrintService getService() {
+        return mService;
+    }
+
+    @Override
+    public void onStartPrinterDiscovery(List<PrinterId> priorityList) {
+        if (mCallbacks != null) {
+            mCallbacks.onStartPrinterDiscovery(priorityList);
+        }
+    }
+
+    @Override
+    public void onStopPrinterDiscovery() {
+        if (mCallbacks != null) {
+            mCallbacks.onStopPrinterDiscovery();
+        }
+    }
+
+    @Override
+    public void onValidatePrinters(List<PrinterId> printerIds) {
+        if (mCallbacks != null) {
+            mCallbacks.onValidatePrinters(printerIds);
+        }
+    }
+
+    @Override
+    public void onStartPrinterStateTracking(PrinterId printerId) {
+        if (mCallbacks != null) {
+            mCallbacks.onStartPrinterStateTracking(printerId);
+        }
+    }
+
+    @Override
+    public void onRequestCustomPrinterIcon(PrinterId printerId,
+            CustomPrinterIconCallback callback) {
+        if (mCallbacks != null) {
+            mCallbacks.onRequestCustomPrinterIcon(printerId, callback);
+        }
+    }
+
+    @Override
+    public void onStopPrinterStateTracking(PrinterId printerId) {
+        if (mCallbacks != null) {
+            mCallbacks.onStopPrinterStateTracking(printerId);
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        if (mCallbacks != null) {
+            mCallbacks.onDestroy();
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
index afd0bc4..00df87d 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
@@ -37,6 +37,7 @@
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
 
 import com.android.frameworks.coretests.R;
 
@@ -145,6 +146,40 @@
     }
 
     @SmallTest
+    public void testDragAndDrop() throws Exception {
+        final String text = "abc def ghi.";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
+        onView(withId(R.id.textview)).perform(
+                mouseDragOnText(text.indexOf("d"), text.indexOf("f") + 1));
+
+        onView(withId(R.id.textview)).perform(
+                mouseDragOnText(text.indexOf("e"), text.length()));
+
+        onView(withId(R.id.textview)).check(matches(withText("abc ghi.def")));
+        onView(withId(R.id.textview)).check(hasSelection(""));
+        assertNoSelectionHandles();
+        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length()));
+    }
+
+    @SmallTest
+    public void testDragAndDrop_longClick() throws Exception {
+        final String text = "abc def ghi.";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
+        onView(withId(R.id.textview)).perform(
+                mouseDragOnText(text.indexOf("d"), text.indexOf("f") + 1));
+
+        onView(withId(R.id.textview)).perform(
+                mouseLongClickAndDragOnText(text.indexOf("e"), text.length()));
+
+        onView(withId(R.id.textview)).check(matches(withText("abc ghi.def")));
+        onView(withId(R.id.textview)).check(hasSelection(""));
+        assertNoSelectionHandles();
+        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length()));
+    }
+
+    @SmallTest
     public void testSelectTextByLongClick() throws Exception {
         final String helloWorld = "Hello world!";
         onView(withId(R.id.textview)).perform(click());
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index edbfef9..5dae4a8 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -159,6 +159,22 @@
     }
 
     @SmallTest
+    public void testDragAndDrop() throws Exception {
+        final String text = "abc def ghi.";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
+        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("e")));
+
+        onView(withId(R.id.textview)).perform(
+                longPressAndDragOnText(text.indexOf("e"), text.length()));
+
+        onView(withId(R.id.textview)).check(matches(withText("abc ghi.def")));
+        onView(withId(R.id.textview)).check(hasSelection(""));
+        assertNoSelectionHandles();
+        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length()));
+    }
+
+    @SmallTest
     public void testDoubleTapToSelect() throws Exception {
         final String helloWorld = "Hello SuetYi!";
         onView(withId(R.id.textview)).perform(click());
diff --git a/docs/html/preview/support.jd b/docs/html/preview/support.jd
index cfd9467..8c392aa 100644
--- a/docs/html/preview/support.jd
+++ b/docs/html/preview/support.jd
@@ -160,20 +160,21 @@
         still perform BTLE and WiFi scans, but only when they are in the foreground. While in the background, those apps will get no results from BTLE and WiFi scans.</li>
     </ul>
   </li>
-  <li>Permission changes
+  <li>Accessing accounts
     <ul>
-      <li>Updated the user interface for permissions and enhanced some of the permissions
-        behaviors.</li>
-      <li>The {@link android.Manifest.permission#GET_ACCOUNTS} permission is now a member of the
-        {@link android.Manifest.permission_group#CONTACTS} permission group and it has a
-        {@code android:protectionLevel} of {@code dangerous}. This change means that when
-        targeting Android 6.0 (API level 23), you must check for and request this permission if
-        your app requires it.
+      <li>Updated the behavior of {@link android.accounts.AccountManager} account
+        discovery methods.
       </li>
-
-      <li>The {@code android.permission.READ_PROFILE} and {@code android.permission.WRITE_PROFILE}
-       permissions have been removed from the {@link android.Manifest.permission_group#CONTACTS}
-       permission group.
+      <li>The GET_ACCOUNTS permission has been deprecated.
+      </li>
+      <li>Apps targeting API level 24 should start the intent returned by
+        newChooseAccountIntent(...) and await the result to acquire a reference
+        to the user's selected account. AccountManager methods like getAccounts and
+        related methods will only return those accounts managed by
+        authenticators that match the signatures of the calling app.
+      </li>
+      <li>Apps targeting API level 23 or earlier will continue to behave as
+        before.
       </li>
     </ul>
   </li>
diff --git a/docs/html/training/id-auth/identify.jd b/docs/html/training/id-auth/identify.jd
index db9ab3a..4c399f9 100644
--- a/docs/html/training/id-auth/identify.jd
+++ b/docs/html/training/id-auth/identify.jd
@@ -15,8 +15,7 @@
 <ol>
   <li><a href="#ForYou">Determine if AccountManager is for You</a></li>
   <li><a href="#TaskTwo">Decide What Type of Account to Use</a></li>
-  <li><a href="#GetPermission">Request GET_ACCOUNT permission</a></li>
-  <li><a href="#TaskFive">Query AccountManager for a List of Accounts</a></li>
+  <li><a href="#QueryAccounts">Query the user for an Account</a></li>
   <li><a href="#IdentifyUser">Use the Account Object to Personalize Your App</a></li>
   <li><a href="#IdIsEnough">Decide Whether an Account Name is Enough</a></li>
 </ol>
@@ -71,48 +70,46 @@
 <h2 id="TaskTwo">Decide What Type of Account to Use</h2>
 
 <p>Android devices can store multiple accounts from many different providers.
-When you query {@link android.accounts.AccountManager} for account names, you can choose to filter
-by
-account type. The account type is a string that uniquely identifies the entity
-that issued the account. For instance, Google accounts have type "com.google,"
-while Twitter uses "com.twitter.android.auth.login."</p>
+When you query {@link android.accounts.AccountManager} for account names, you
+can choose to filter by account type. The account type is a string that
+uniquely identifies the entity that issued the account. For instance, Google
+accounts have type "com.google," while Twitter uses
+"com.twitter.android.auth.login."</p>
 
+<h2 id="QueryAccounts">Query the user for an Account</h2>
 
-<h2 id="GetPermission">Request GET_ACCOUNT permission</h2>
-
-<p>In order to get a list of accounts on the device, your app needs the {@link
-android.Manifest.permission#GET_ACCOUNTS}
-permission. Add a <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">{@code
-<uses-permission>}</a> tag in your manifest file to request
-this permission:</p>
+<p>Once an account type has been determined, you can prompt the user with an
+account chooser as follows:
 
 <pre>
-&lt;manifest ... >
-    &lt;uses-permission android:name="android.permission.GET_ACCOUNTS" /&gt;
-    ...
-&lt;/manifest>
+AccountManager am = AccountManager.get(this);  // "this" reference the current Context
+Intent chooserIntent = am.newChooseAccountIntent(
+        null, // currently select account
+        null, // list of accounts that are allowed to be shown
+        new String[] { "com.google" }, // Only allow the user to select Google accounts
+        false,
+        null,  // description text
+        null, // add account auth token type
+        null, // required features for added accounts
+        null);  // options for adding an account
+this.startActivityForResult(chooserIntent, MY_REQUEST_CODE);
 </pre>
 
-
-<h2 id="TaskFive">Query AccountManager for a List of Accounts</h2>
-
-<p>Once you decide what account type you're interested in, you need to query for accounts of that
-type. Get an instance of {@link android.accounts.AccountManager} by calling {@link
-android.accounts.AccountManager#get(android.content.Context) AccountManager.get()}. Then use that
-instance to call {@link android.accounts.AccountManager#getAccountsByType(java.lang.String)
-getAccountsByType()}.</p>
+<p>Once the chooser intent is started, the user will be presented with a list of
+appropriately typed accounts. From this list they will select one which will be
+returned to your app upon onActivityResult as follows:
 
 <pre>
-AccountManager am = AccountManager.get(this); // "this" references the current Context
-
-Account[] accounts = am.getAccountsByType("com.google");
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    if (requestCode == MY_REQUEST_CODE && resultCode == RESULT_OK) {
+        String name = data.getStringExtra(AccountManage.KEY_ACCOUNT_NAME);
+        String type = data.getStringExtra(AccountManage.KEY_ACCOUNT_TYPE);
+        Account selectedAccount = new Account(name, type);
+        doSomethingWithSelectedAccount(selectedAccount);
+    }
+}
 </pre>
 
-<p>This returns an array of {@link android.accounts.Account} objects. If there's more than one
-{@link android.accounts.Account} in
-the array, you should present a dialog asking the user to select one.</p>
-
-
 <h2 id="IdentifyUser">Use the Account Object to Personalize Your App</h2>
 
 <p>The {@link android.accounts.Account} object contains an account name, which for Google accounts
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 84ca546..1857345 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -19,7 +19,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.Animator.AnimatorListener;
-import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.res.ColorStateList;
@@ -141,15 +140,6 @@
     /** Local, mutable animator set. */
     private final AnimatorSet mAnimatorSet = new AnimatorSet();
 
-
-    private final ValueAnimator.AnimatorUpdateListener mUpdateListener =
-            new ValueAnimator.AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator animation) {
-                    invalidateSelf();
-                }
-            };
-
     /**
      * The resources against which this drawable was created. Used to attempt
      * to inflate animators if applyTheme() doesn't get called.
@@ -211,6 +201,9 @@
     @Override
     public void draw(Canvas canvas) {
         mAnimatedVectorState.mVectorDrawable.draw(canvas);
+        if (isStarted()) {
+            invalidateSelf();
+        }
     }
 
     @Override
@@ -493,7 +486,6 @@
          *            animators, or {@code null} if not available
          */
         public void prepareLocalAnimators(@NonNull AnimatorSet animatorSet,
-                @NonNull ValueAnimator.AnimatorUpdateListener updateListener,
                 @Nullable Resources res) {
             // Check for uninflated animators. We can remove this after we add
             // support for Animator.applyTheme(). See comments in inflate().
@@ -519,17 +511,6 @@
                     final Animator nextAnim = prepareLocalAnimator(i);
                     builder.with(nextAnim);
                 }
-
-                // Setup a value animator to get animation update callbacks.
-                long totalDuration = animatorSet.getTotalDuration();
-                ValueAnimator updateAnim = ValueAnimator.ofFloat(0f, 1f);
-                if (totalDuration == ValueAnimator.DURATION_INFINITE) {
-                    updateAnim.setRepeatCount(ValueAnimator.INFINITE);
-                } else {
-                    updateAnim.setDuration(totalDuration);
-                }
-                updateAnim.addUpdateListener(updateListener);
-                builder.with(updateAnim);
             }
         }
 
@@ -622,7 +603,7 @@
     @NonNull
     private void ensureAnimatorSet() {
         if (!mHasAnimatorSet) {
-            mAnimatedVectorState.prepareLocalAnimators(mAnimatorSet, mUpdateListener, mRes);
+            mAnimatedVectorState.prepareLocalAnimators(mAnimatorSet, mRes);
             mHasAnimatorSet = true;
             mRes = null;
         }
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 8ba6318..fc40554 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -4,6 +4,11 @@
 
 HWUI_NEW_OPS := true
 
+# Enables fine-grained GLES error checking
+# If set to true, every GLES call is wrapped & error checked
+# Has moderate overhead
+HWUI_ENABLE_OPENGL_VALIDATION := false
+
 hwui_src_files := \
     font/CacheTexture.cpp \
     font/Font.cpp \
@@ -157,6 +162,13 @@
         frameworks/rs
 endif
 
+ifeq (true, $(HWUI_ENABLE_OPENGL_VALIDATION))
+    hwui_cflags += -include debug/wrap_gles.h
+    hwui_src_files += debug/wrap_gles.cpp
+    hwui_c_includes += frameworks/native/opengl/libs/GLES2
+    hwui_cflags += -DDEBUG_OPENGL=3
+endif
+
 
 # ------------------------
 # static library
@@ -188,8 +200,8 @@
         -DHWUI_NULL_GPU
 LOCAL_SRC_FILES := \
         $(hwui_src_files) \
-        tests/common/nullegl.cpp \
-        tests/common/nullgles.cpp
+        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)
 
@@ -235,7 +247,8 @@
     tests/unit/LinearAllocatorTests.cpp \
     tests/unit/VectorDrawableTests.cpp \
     tests/unit/OffscreenBufferPoolTests.cpp \
-    tests/unit/StringUtilsTests.cpp
+    tests/unit/StringUtilsTests.cpp \
+    tests/unit/BufferPoolTests.cpp
 
 ifeq (true, $(HWUI_NEW_OPS))
     LOCAL_SRC_FILES += \
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 00381ee..7ecc743 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -784,9 +784,7 @@
                 .build();
         renderer.renderGlop(state, glop);
     }
-    GL_CHECKPOINT();
     renderer.renderState().layerPool().putOrDelete(*op.layerHandle);
-    GL_CHECKPOINT();
 }
 
 } // namespace uirenderer
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index e65746e..5736c70 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -49,7 +49,8 @@
     // attach the texture to the FBO
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
             offscreenBuffer->texture.id(), 0);
-    LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "startLayer FAILED");
+    GL_CHECKPOINT(LOW);
+
     LOG_ALWAYS_FATAL_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
             "framebuffer incomplete!");
 
@@ -63,7 +64,7 @@
     if (mRenderTarget.stencil) {
         // if stencil was used for clipping, detach it and return it to pool
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
-        LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "glfbrb endlayer failed");
+        GL_CHECKPOINT(MODERATE);
         mCaches.renderBufferCache.put(mRenderTarget.stencil);
         mRenderTarget.stencil = nullptr;
     }
@@ -74,8 +75,7 @@
 
     // Detach the texture from the FBO
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
-    LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "endLayer FAILED, bound fbo = %u",
-            mRenderState.getFramebuffer());
+    GL_CHECKPOINT(LOW);
     mRenderState.deleteFramebuffer(mRenderTarget.frameBufferId);
     mRenderTarget.frameBufferId = 0;
 }
@@ -139,8 +139,6 @@
     mCaches.pathCache.trim();
     mCaches.tessellationCache.trim();
 
-    GL_CHECKPOINT();
-
 #if DEBUG_MEMORY_USAGE
     mCaches.dumpMemoryUsage();
 #else
@@ -331,9 +329,28 @@
     mRenderState.invokeFunctor(op.functor, DrawGlInfo::kModeDraw, &info);
 }
 
+#define VALIDATE_RECT_ARG(rect, arg) \
+        ((isnanf(rect.arg) || rect.arg < -10000 || rect.arg > 10000) ? (\
+            ALOGW("suspicious " #rect "." #arg "! %f", rect.arg),\
+            false) : true)
+
+#define VALIDATE_RECT(rect) \
+    VALIDATE_RECT_ARG(rect, bottom) & \
+    VALIDATE_RECT_ARG(rect, left) & \
+    VALIDATE_RECT_ARG(rect, top) & \
+    VALIDATE_RECT_ARG(rect, right)
+
 void BakedOpRenderer::dirtyRenderTarget(const Rect& uiDirty) {
     if (mRenderTarget.offscreenBuffer) {
-        android::Rect dirty(uiDirty.left, uiDirty.top, uiDirty.right, uiDirty.bottom);
+        bool valid = VALIDATE_RECT(uiDirty);
+        android::Rect dirty;
+        if (valid) {
+            dirty = android::Rect(uiDirty.left, uiDirty.top, uiDirty.right, uiDirty.bottom);
+        } else {
+            dirty = android::Rect(0, 0,
+                    mRenderTarget.offscreenBuffer->viewportWidth,
+                    mRenderTarget.offscreenBuffer->viewportHeight);
+        }
         mRenderTarget.offscreenBuffer->region.orSelf(dirty);
     }
 }
diff --git a/libs/hwui/BufferPool.h b/libs/hwui/BufferPool.h
new file mode 100644
index 0000000..005b399
--- /dev/null
+++ b/libs/hwui/BufferPool.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/Canvas.h b/libs/hwui/Canvas.h
index 0643a54..9dfe454 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -27,6 +27,22 @@
 
 namespace android {
 
+namespace SaveFlags {
+
+// These must match the corresponding Canvas API constants.
+enum {
+    Matrix        = 0x01,
+    Clip          = 0x02,
+    HasAlphaLayer = 0x04,
+    ClipToLayer   = 0x10,
+
+    // Helper constant
+    MatrixClip    = Matrix | Clip,
+};
+typedef uint32_t Flags;
+
+} // namespace SaveFlags
+
 class ANDROID_API Canvas {
 public:
     virtual ~Canvas() {};
@@ -70,16 +86,17 @@
 // ----------------------------------------------------------------------------
 // Canvas state operations
 // ----------------------------------------------------------------------------
+
     // Save (layer)
     virtual int getSaveCount() const = 0;
-    virtual int save(SkCanvas::SaveFlags flags) = 0;
+    virtual int save(SaveFlags::Flags flags) = 0;
     virtual void restore() = 0;
     virtual void restoreToCount(int saveCount) = 0;
 
     virtual int saveLayer(float left, float top, float right, float bottom,
-                const SkPaint* paint, SkCanvas::SaveFlags flags) = 0;
+                const SkPaint* paint, SaveFlags::Flags flags) = 0;
     virtual int saveLayerAlpha(float left, float top, float right, float bottom,
-            int alpha, SkCanvas::SaveFlags flags) = 0;
+            int alpha, SaveFlags::Flags flags) = 0;
 
     // Matrix
     virtual void getMatrix(SkMatrix* outMatrix) const = 0;
diff --git a/libs/hwui/CanvasState.cpp b/libs/hwui/CanvasState.cpp
index cf2726b..43ff33f 100644
--- a/libs/hwui/CanvasState.cpp
+++ b/libs/hwui/CanvasState.cpp
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#include <SkCanvas.h>
-
+#include "Canvas.h"
 #include "CanvasState.h"
 #include "utils/MathUtils.h"
 
@@ -54,8 +53,7 @@
     }
 
     freeAllSnapshots();
-    mSnapshot = allocSnapshot(&mFirstSnapshot,
-            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    mSnapshot = allocSnapshot(&mFirstSnapshot, SaveFlags::MatrixClip);
     mSnapshot->setRelativeLightCenter(Vector3());
     mSaveCount = 1;
 }
@@ -72,8 +70,7 @@
     }
 
     freeAllSnapshots();
-    mSnapshot = allocSnapshot(&mFirstSnapshot,
-            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    mSnapshot = allocSnapshot(&mFirstSnapshot, SaveFlags::MatrixClip);
     mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
     mSnapshot->fbo = mCanvas.getTargetFbo();
     mSnapshot->setRelativeLightCenter(lightCenter);
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index e98fa04..748edef 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -17,8 +17,18 @@
 #ifndef ANDROID_HWUI_DEBUG_H
 #define ANDROID_HWUI_DEBUG_H
 
+#define DEBUG_LEVEL_HIGH 3
+#define DEBUG_LEVEL_MODERATE 2
+#define DEBUG_LEVEL_LOW 1
+#define DEBUG_LEVEL_NONE 0
+
 // Turn on to check for OpenGL errors on each frame
-#define DEBUG_OPENGL 1
+// Note DEBUG_LEVEL_HIGH for DEBUG_OPENGL is only setable by enabling
+// HWUI_ENABLE_OPENGL_VALIDATION when building HWUI. Similarly if
+// HWUI_ENABLE_OPENGL_VALIDATION is set then this is always DEBUG_LEVEL_HIGH
+#ifndef DEBUG_OPENGL
+#define DEBUG_OPENGL DEBUG_LEVEL_LOW
+#endif
 
 // Turn on to enable initialization information
 #define DEBUG_INIT 0
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index a1825c5..1b0f424 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include <SkCanvas.h>
-
 #include <utils/Trace.h>
 #include <ui/Rect.h>
 #include <ui/Region.h>
@@ -419,7 +417,7 @@
  * beginning of the frame. This would avoid targetting and removing an FBO in the middle of a frame.
  *
  * saveLayer operations should be pulled to the beginning of the frame if the canvas doesn't have a
- * complex clip, and if the flags (kClip_SaveFlag & kClipToLayer_SaveFlag) are set.
+ * complex clip, and if the flags (SaveFlags::Clip & SaveFlags::ClipToLayer) are set.
  */
 void DeferredDisplayList::addSaveLayer(OpenGLRenderer& renderer,
         SaveLayerOp* op, int newSaveCount) {
@@ -438,7 +436,7 @@
     int saveFlags = op->getFlags();
     DEFER_LOGD("%p adding saveOp %p, flags %x, new count %d", this, op, saveFlags, newSaveCount);
 
-    if (recordingComplexClip() && (saveFlags & SkCanvas::kClip_SaveFlag)) {
+    if (recordingComplexClip() && (saveFlags & SaveFlags::Clip)) {
         // store and replay the save operation, as it may be needed to correctly playback the clip
         DEFER_LOGD("    adding save barrier with new save count %d", newSaveCount);
         storeStateOpBarrier(renderer, op);
@@ -621,7 +619,7 @@
             this, newSaveCount, mBatches.size());
 
     // store displayState for the restore operation, as it may be associated with a saveLayer that
-    // doesn't have kClip_SaveFlag set
+    // doesn't have SaveFlags::Clip set
     DeferredDisplayState* state = createState();
     renderer.storeDisplayState(*state, getStateOpDeferFlags());
     mBatches.push_back(new RestoreToCountBatch(op, state, newSaveCount));
@@ -654,7 +652,7 @@
     renderer.eventMark("Flush");
 
     // save and restore so that reordering doesn't affect final state
-    renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    renderer.save(SaveFlags::MatrixClip);
 
     if (CC_LIKELY(avoidOverdraw())) {
         for (unsigned int i = 1; i < mBatches.size(); i++) {
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 759c12a..384e64d 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -102,7 +102,7 @@
     return mSkiaCanvasProxy.get();
 }
 
-int DisplayListCanvas::save(SkCanvas::SaveFlags flags) {
+int DisplayListCanvas::save(SaveFlags::Flags flags) {
     addStateOp(new (alloc()) SaveOp((int) flags));
     return mState.save((int) flags);
 }
@@ -125,9 +125,9 @@
 }
 
 int DisplayListCanvas::saveLayer(float left, float top, float right, float bottom,
-        const SkPaint* paint, SkCanvas::SaveFlags flags) {
+        const SkPaint* paint, SaveFlags::Flags flags) {
     // force matrix/clip isolation for layer
-    flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag;
+    flags |= SaveFlags::MatrixClip;
 
     paint = refPaint(paint);
     addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, (int) flags));
@@ -232,7 +232,7 @@
 
 void DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top,
         const SkPaint* paint) {
-    save(SkCanvas::kMatrix_SaveFlag);
+    save(SaveFlags::Matrix);
     translate(left, top);
     drawBitmap(&bitmap, paint);
     restore();
@@ -253,7 +253,7 @@
         drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
                    dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
     } else {
-        save(SkCanvas::kMatrix_SaveFlag);
+        save(SaveFlags::Matrix);
         concat(matrix);
         drawBitmap(&bitmap, paint);
         restore();
@@ -269,7 +269,7 @@
             && (srcBottom - srcTop == dstBottom - dstTop)
             && (srcRight - srcLeft == dstRight - dstLeft)) {
         // transform simple rect to rect drawing case into position bitmap ops, since they merge
-        save(SkCanvas::kMatrix_SaveFlag);
+        save(SaveFlags::Matrix);
         translate(dstLeft, dstTop);
         drawBitmap(&bitmap, paint);
         restore();
@@ -283,7 +283,7 @@
                 // Apply the scale transform on the canvas, so that the shader
                 // effectively calculates positions relative to src rect space
 
-                save(SkCanvas::kMatrix_SaveFlag);
+                save(SaveFlags::Matrix);
                 translate(dstLeft, dstTop);
                 scale(scaleX, scaleY);
 
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index 72fc100..f1cfa08 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -128,14 +128,14 @@
 // ----------------------------------------------------------------------------
     // Save (layer)
     virtual int getSaveCount() const override { return mState.getSaveCount(); }
-    virtual int save(SkCanvas::SaveFlags flags) override;
+    virtual int save(SaveFlags::Flags flags) override;
     virtual void restore() override;
     virtual void restoreToCount(int saveCount) override;
 
     virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
-        SkCanvas::SaveFlags flags) override;
+        SaveFlags::Flags flags) override;
     virtual int saveLayerAlpha(float left, float top, float right, float bottom,
-            int alpha, SkCanvas::SaveFlags flags) override {
+            int alpha, SaveFlags::Flags flags) override {
         SkPaint paint;
         paint.setAlpha(alpha);
         return saveLayer(left, top, right, bottom, &paint, flags);
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index c4c655b..a457212 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -16,6 +16,7 @@
 
 #include "FrameBuilder.h"
 
+#include "Canvas.h"
 #include "LayerUpdateQueue.h"
 #include "RenderNode.h"
 #include "renderstate/OffscreenBufferPool.h"
@@ -23,7 +24,6 @@
 #include "utils/PaintUtils.h"
 #include "utils/TraceUtils.h"
 
-#include <SkCanvas.h>
 #include <SkPathOps.h>
 #include <utils/TypeHelpers.h>
 
@@ -33,6 +33,15 @@
 FrameBuilder::FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip,
         uint32_t viewportWidth, uint32_t viewportHeight,
         const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter)
+        : FrameBuilder(layers, clip, viewportWidth, viewportHeight, nodes, lightCenter,
+                Rect(0, 0, 0, 0)) {
+}
+
+
+FrameBuilder::FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip,
+        uint32_t viewportWidth, uint32_t viewportHeight,
+        const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter,
+        const Rect &contentDrawBounds)
         : mCanvasState(*this) {
     ATRACE_NAME("prepare drawing commands");
 
@@ -72,14 +81,56 @@
         }
     }
 
-    // Defer Fbo0
+    // It there are multiple render nodes, they are laid out as follows:
+    // #0 - backdrop (content + caption)
+    // #1 - content (positioned at (0,0) and clipped to - its bounds mContentDrawBounds)
+    // #2 - additional overlay nodes
+    // Usually the backdrop cannot be seen since it will be entirely covered by the content. While
+    // resizing however it might become partially visible. The following render loop will crop the
+    // backdrop against the content and draw the remaining part of it. It will then draw the content
+    // cropped to the backdrop (since that indicates a shrinking of the window).
+    //
+    // Additional nodes will be drawn on top with no particular clipping semantics.
+
+    // The bounds of the backdrop against which the content should be clipped.
+    Rect backdropBounds = contentDrawBounds;
+    // Usually the contents bounds should be mContentDrawBounds - however - we will
+    // move it towards the fixed edge to give it a more stable appearance (for the moment).
+    // If there is no content bounds we ignore the layering as stated above and start with 2.
+    int layer = (contentDrawBounds.isEmpty() || nodes.size() == 1) ? 2 : 0;
+
     for (const sp<RenderNode>& node : nodes) {
         if (node->nothingToDraw()) continue;
         node->computeOrdering();
+        int count = mCanvasState.save(SaveFlags::MatrixClip);
 
-        int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
+        if (layer == 0) {
+            const RenderProperties& properties = node->properties();
+            Rect targetBounds(properties.getLeft(), properties.getTop(),
+                              properties.getRight(), properties.getBottom());
+            // Move the content bounds towards the fixed corner of the backdrop.
+            const int x = targetBounds.left;
+            const int y = targetBounds.top;
+            // Remember the intersection of the target bounds and the intersection bounds against
+            // which we have to crop the content.
+            backdropBounds.set(x, y, x + backdropBounds.getWidth(), y + backdropBounds.getHeight());
+            backdropBounds.doIntersect(targetBounds);
+        } else if (layer == 1) {
+            // We shift and clip the content to match its final location in the window.
+            const float left = contentDrawBounds.left;
+            const float top = contentDrawBounds.top;
+            const float dx = backdropBounds.left - left;
+            const float dy = backdropBounds.top - top;
+            const float width = backdropBounds.getWidth();
+            const float height = backdropBounds.getHeight();
+            mCanvasState.translate(dx, dy);
+            // It gets cropped against the bounds of the backdrop to stay inside.
+            mCanvasState.clipRect(left, top, left + width, top + height, SkRegion::kIntersect_Op);
+        }
+
         deferNodePropsAndOps(*node);
         mCanvasState.restoreToCount(count);
+        layer++;
     }
 }
 
@@ -327,7 +378,7 @@
 
 void FrameBuilder::deferProjectedChildren(const RenderNode& renderNode) {
     const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath();
-    int count = mCanvasState.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    int count = mCanvasState.save(SaveFlags::MatrixClip);
 
     // can't be null, since DL=null node rejection happens before deferNodePropsAndOps
     const DisplayList& displayList = *(renderNode.getDisplayList());
@@ -348,7 +399,7 @@
     for (size_t i = 0; i < renderNode.mProjectedNodes.size(); i++) {
         RenderNodeOp* childOp = renderNode.mProjectedNodes[i];
 
-        int restoreTo = mCanvasState.save(SkCanvas::kMatrix_SaveFlag);
+        int restoreTo = mCanvasState.save(SaveFlags::Matrix);
         mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor);
         deferRenderNodeOpImpl(*childOp);
         mCanvasState.restoreToCount(restoreTo);
@@ -392,7 +443,7 @@
 
 void FrameBuilder::deferRenderNodeOpImpl(const RenderNodeOp& op) {
     if (op.renderNode->nothingToDraw()) return;
-    int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
+    int count = mCanvasState.save(SaveFlags::MatrixClip);
 
     // apply state from RecordedOp (clip first, since op's clip is transformed by current matrix)
     mCanvasState.writableSnapshot()->mutateClipArea().applyClip(op.localClip,
@@ -450,6 +501,10 @@
     BakedOpState* bakedState = tryBakeOpState(op);
     if (!bakedState) return; // quick rejected
 
+    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
+
+    // TODO: Fix this ( b/26569206 )
+/*
     // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
     // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
     // MergingDrawBatch::canMergeWith()
@@ -464,6 +519,7 @@
     } else {
         currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
     }
+*/
 }
 
 void FrameBuilder::deferBitmapMeshOp(const BitmapMeshOp& op) {
@@ -597,7 +653,7 @@
         const Rect& repaintRect,
         const Vector3& lightCenter,
         const BeginLayerOp* beginLayerOp, RenderNode* renderNode) {
-    mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
+    mCanvasState.save(SaveFlags::MatrixClip);
     mCanvasState.writableSnapshot()->initializeViewport(layerWidth, layerHeight);
     mCanvasState.writableSnapshot()->roundRectClipState = nullptr;
     mCanvasState.writableSnapshot()->setRelativeLightCenter(lightCenter);
diff --git a/libs/hwui/FrameBuilder.h b/libs/hwui/FrameBuilder.h
index bd01850..dea9934 100644
--- a/libs/hwui/FrameBuilder.h
+++ b/libs/hwui/FrameBuilder.h
@@ -59,6 +59,11 @@
             uint32_t viewportWidth, uint32_t viewportHeight,
             const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter);
 
+    FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip,
+            uint32_t viewportWidth, uint32_t viewportHeight,
+            const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter,
+            const Rect &contentDrawBounds);
+
     virtual ~FrameBuilder() {}
 
     /**
@@ -100,30 +105,30 @@
         // Relay through layers in reverse order, since layers
         // later in the list will be drawn by earlier ones
         for (int i = mLayerBuilders.size() - 1; i >= 1; i--) {
-            GL_CHECKPOINT();
+            GL_CHECKPOINT(MODERATE);
             LayerBuilder& layer = *(mLayerBuilders[i]);
             if (layer.renderNode) {
                 // cached HW layer - can't skip layer if empty
                 renderer.startRepaintLayer(layer.offscreenBuffer, layer.repaintRect);
-                GL_CHECKPOINT();
+                GL_CHECKPOINT(MODERATE);
                 layer.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
-                GL_CHECKPOINT();
+                GL_CHECKPOINT(MODERATE);
                 renderer.endLayer();
             } else if (!layer.empty()) { // save layer - skip entire layer if empty
                 layer.offscreenBuffer = renderer.startTemporaryLayer(layer.width, layer.height);
-                GL_CHECKPOINT();
+                GL_CHECKPOINT(MODERATE);
                 layer.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
-                GL_CHECKPOINT();
+                GL_CHECKPOINT(MODERATE);
                 renderer.endLayer();
             }
         }
 
-        GL_CHECKPOINT();
+        GL_CHECKPOINT(MODERATE);
         const LayerBuilder& fbo0 = *(mLayerBuilders[0]);
         renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect);
-        GL_CHECKPOINT();
+        GL_CHECKPOINT(MODERATE);
         fbo0.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
-        GL_CHECKPOINT();
+        GL_CHECKPOINT(MODERATE);
         renderer.endFrame(fbo0.repaintRect);
     }
 
diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h
index f8013ab..0baca39 100644
--- a/libs/hwui/FrameInfo.h
+++ b/libs/hwui/FrameInfo.h
@@ -118,6 +118,10 @@
         set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
     }
 
+    const int64_t* data() const {
+        return mFrameInfo;
+    }
+
     inline int64_t operator[](FrameInfoIndex index) const {
         return get(index);
     }
diff --git a/libs/hwui/FrameStatsObserver.h b/libs/hwui/FrameStatsObserver.h
new file mode 100644
index 0000000..7abc9f1
--- /dev/null
+++ b/libs/hwui/FrameStatsObserver.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#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
diff --git a/libs/hwui/FrameStatsReporter.h b/libs/hwui/FrameStatsReporter.h
new file mode 100644
index 0000000..b8a9432
--- /dev/null
+++ b/libs/hwui/FrameStatsReporter.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 0f219e4..3123e8e 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -407,7 +407,6 @@
         renderState.bindFramebuffer(fbo);
 
         glGenTextures(1, &texture);
-        GL_CHECKPOINT();
 
         caches.textureState().activateTexture(0);
         caches.textureState().bindTexture(texture);
@@ -422,11 +421,9 @@
 
         glTexImage2D(GL_TEXTURE_2D, 0, format, bitmap->width(), bitmap->height(),
                 0, format, type, nullptr);
-        GL_CHECKPOINT();
 
         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                 GL_TEXTURE_2D, texture, 0);
-        GL_CHECKPOINT();
 
         {
             LayerRenderer renderer(renderState, layer);
@@ -437,8 +434,6 @@
             renderer.translate(0.0f, bitmap->height());
             renderer.scale(1.0f, -1.0f);
 
-            GL_CHECKPOINT();
-
             {
                 Rect bounds;
                 bounds.set(0.0f, 0.0f, bitmap->width(), bitmap->height());
@@ -447,7 +442,6 @@
                 glReadPixels(0, 0, bitmap->width(), bitmap->height(), format,
                         type, bitmap->getPixels());
 
-                GL_CHECKPOINT();
             }
 
             status = true;
@@ -460,6 +454,8 @@
         renderState.deleteFramebuffer(fbo);
         renderState.setViewport(previousViewportWidth, previousViewportHeight);
 
+        GL_CHECKPOINT(MODERATE);
+
         return status;
     }
     return false;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index db017fe..6c2e244 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -17,6 +17,7 @@
 #include <GpuMemoryTracker.h>
 #include "OpenGLRenderer.h"
 
+#include "Canvas.h"
 #include "DeferredDisplayList.h"
 #include "GammaFontRenderer.h"
 #include "Glop.h"
@@ -39,7 +40,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <SkCanvas.h>
 #include <SkColor.h>
 #include <SkPaintDefaults.h>
 #include <SkPathOps.h>
@@ -195,7 +195,7 @@
     }
 
     if (!suppressErrorChecks()) {
-        GL_CHECKPOINT();
+        GL_CHECKPOINT(MODERATE);
 
 #if DEBUG_MEMORY_USAGE
         mCaches.dumpMemoryUsage();
@@ -472,7 +472,7 @@
 int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
         const SkPaint* paint, int flags, const SkPath* convexMask) {
     // force matrix/clip isolation for layer
-    flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag;
+    flags |= SaveFlags::MatrixClip;
 
     const int count = mState.saveSnapshot(flags);
 
@@ -531,7 +531,7 @@
         const SkPaint* paint, int flags) {
     const int count = mState.saveSnapshot(flags);
 
-    if (!mState.currentlyIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) {
+    if (!mState.currentlyIgnored() && (flags & SaveFlags::ClipToLayer)) {
         // initialize the snapshot as though it almost represents an FBO layer so deferred draw
         // operations will be able to store and restore the current clip and transform info, and
         // quick rejection will be correct (for display lists)
@@ -558,7 +558,7 @@
  * and the frame buffer still receive every drawing command. For instance, if a
  * layer is created and a shape intersecting the bounds of the layers and the
  * framebuffer is draw, the shape will be drawn on both (unless the layer was
- * created with the SkCanvas::kClipToLayer_SaveFlag flag.)
+ * created with the SaveFlags::ClipToLayer flag.)
  *
  * A way to implement layers is to create an FBO for each layer, backed by an RGBA
  * texture. Unfortunately, this is inefficient as it requires every primitive to
@@ -608,7 +608,7 @@
     LAYER_LOGD("Requesting layer %.2fx%.2f", right - left, bottom - top);
     LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize());
 
-    const bool fboLayer = flags & SkCanvas::kClipToLayer_SaveFlag;
+    const bool fboLayer = flags & SaveFlags::ClipToLayer;
 
     // Window coordinates of the layer
     Rect clip;
@@ -890,7 +890,7 @@
     if (CC_UNLIKELY(layer->region.isEmpty())) return; // nothing to draw
 
     if (layer->getConvexMask()) {
-        save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
+        save(SaveFlags::MatrixClip);
 
         // clip to the area of the layer the mask can be larger
         clipRect(rect.left, rect.top, rect.right, rect.bottom, SkRegion::kIntersect_Op);
@@ -2233,7 +2233,7 @@
     if (layer->isTextureLayer()) {
         transform = &layer->getTransform();
         if (!transform->isIdentity()) {
-            save(SkCanvas::kMatrix_SaveFlag);
+            save(SaveFlags::Matrix);
             concatMatrix(*transform);
         }
     }
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 78855e5..328e291 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -92,7 +92,7 @@
 // android/graphics/Canvas state operations
 // ----------------------------------------------------------------------------
 // Save (layer)
-int RecordingCanvas::save(SkCanvas::SaveFlags flags) {
+int RecordingCanvas::save(SaveFlags::Flags flags) {
     return mState.save((int) flags);
 }
 
@@ -105,10 +105,10 @@
 }
 
 int RecordingCanvas::saveLayer(float left, float top, float right, float bottom,
-        const SkPaint* paint, SkCanvas::SaveFlags flags) {
+        const SkPaint* paint, SaveFlags::Flags flags) {
     // force matrix/clip isolation for layer
-    flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag;
-    bool clippedLayer = flags & SkCanvas::kClipToLayer_SaveFlag;
+    flags |= SaveFlags::MatrixClip;
+    bool clippedLayer = flags & SaveFlags::ClipToLayer;
 
     const Snapshot& previous = *mState.currentSnapshot();
 
@@ -128,7 +128,7 @@
         // unlikely case where an unclipped savelayer is recorded with a clip it can use,
         // as none of its unaffected/unclipped area is visible
         clippedLayer = true;
-        flags |= SkCanvas::kClipToLayer_SaveFlag;
+        flags |= SaveFlags::ClipToLayer;
     }
 
     visibleBounds.doIntersect(previous.getRenderTargetClip());
@@ -424,7 +424,7 @@
 
 // Bitmap-based
 void RecordingCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint) {
-    save(SkCanvas::kMatrix_SaveFlag);
+    save(SaveFlags::Matrix);
     translate(left, top);
     drawBitmap(&bitmap, paint);
     restore();
@@ -445,7 +445,7 @@
         drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
                    dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
     } else {
-        save(SkCanvas::kMatrix_SaveFlag);
+        save(SaveFlags::Matrix);
         concat(matrix);
         drawBitmap(&bitmap, paint);
         restore();
@@ -461,7 +461,7 @@
             && (srcBottom - srcTop == dstBottom - dstTop)
             && (srcRight - srcLeft == dstRight - dstLeft)) {
         // transform simple rect to rect drawing case into position bitmap ops, since they merge
-        save(SkCanvas::kMatrix_SaveFlag);
+        save(SaveFlags::Matrix);
         translate(dstLeft, dstTop);
         drawBitmap(&bitmap, paint);
         restore();
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 8aa7506..786f96e 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -108,14 +108,14 @@
 // ----------------------------------------------------------------------------
     // Save (layer)
     virtual int getSaveCount() const override { return mState.getSaveCount(); }
-    virtual int save(SkCanvas::SaveFlags flags) override;
+    virtual int save(SaveFlags::Flags flags) override;
     virtual void restore() override;
     virtual void restoreToCount(int saveCount) override;
 
     virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
-        SkCanvas::SaveFlags flags) override;
+        SaveFlags::Flags flags) override;
     virtual int saveLayerAlpha(float left, float top, float right, float bottom,
-            int alpha, SkCanvas::SaveFlags flags) override {
+            int alpha, SaveFlags::Flags flags) override {
         SkPaint paint;
         paint.setAlpha(alpha);
         return saveLayer(left, top, right, bottom, &paint, flags);
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index ae690fd..d4588ed 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -33,8 +33,6 @@
 #include "protos/hwui.pb.h"
 #include "protos/ProtoHelpers.h"
 
-#include <SkCanvas.h>
-
 #include <algorithm>
 #include <sstream>
 #include <string>
@@ -105,8 +103,7 @@
             (isRenderable() ? "" : ", empty"),
             (properties().getProjectBackwards() ? ", projected" : ""),
             (mLayer != nullptr ? ", on HW Layer" : ""));
-    ALOGD("%*s%s %d", level * 2, "", "Save",
-            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    ALOGD("%*s%s %d", level * 2, "", "Save", SaveFlags::MatrixClip);
 
     properties().debugOutputProperties(level);
 
@@ -574,7 +571,7 @@
                     layerBounds.left, layerBounds.top,
                     layerBounds.right, layerBounds.bottom,
                     (int) (properties().getAlpha() * 255),
-                    SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kClipToLayer_SaveFlag);
+                    SaveFlags::HasAlphaLayer | SaveFlags::ClipToLayer);
             handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
         }
 
@@ -875,7 +872,7 @@
 
     // Apply the base transform of the parent of the 3d children. This isolates
     // 3d children of the current chunk from transformations made in previous chunks.
-    int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
+    int rootRestoreTo = renderer.save(SaveFlags::Matrix);
     renderer.setGlobalMatrix(initialTransform);
 
     /**
@@ -919,7 +916,7 @@
 
         // only the actual child DL draw needs to be in save/restore,
         // since it modifies the renderer's matrix
-        int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
+        int restoreTo = renderer.save(SaveFlags::Matrix);
 
         DrawRenderNodeOp* childOp = zTranslatedNodes[drawIndex].value;
 
@@ -941,7 +938,7 @@
     int restoreTo = renderer.getSaveCount();
 
     LinearAllocator& alloc = handler.allocator();
-    handler(new (alloc) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag),
+    handler(new (alloc) SaveOp(SaveFlags::MatrixClip),
             PROPERTY_SAVECOUNT, properties().getClipToBounds());
 
     // Transform renderer to match background we're projecting onto
@@ -966,7 +963,7 @@
         renderNodeOp_t* childOp = mProjectedNodes[i];
 
         // matrix save, concat, and restore can be done safely without allocating operations
-        int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
+        int restoreTo = renderer.save(SaveFlags::Matrix);
         renderer.concatMatrix(childOp->transformFromCompositingAncestor);
         childOp->skipInOrderDraw = false; // this is horrible, I'm so sorry everyone
         handler(childOp, renderer.getSaveCount() - 1, properties().getClipToBounds());
@@ -1027,11 +1024,11 @@
 
     LinearAllocator& alloc = handler.allocator();
     int restoreTo = renderer.getSaveCount();
-    handler(new (alloc) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag),
+    handler(new (alloc) SaveOp(SaveFlags::MatrixClip),
             PROPERTY_SAVECOUNT, properties().getClipToBounds());
 
     DISPLAY_LIST_LOGD("%*sSave %d %d", (handler.level() + 1) * 2, "",
-            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
+            SaveFlags::MatrixClip, restoreTo);
 
     if (useViewProperties) {
         setViewProperties<T>(renderer, handler);
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
index ce1bd6a..b848af4 100644
--- a/libs/hwui/RenderProperties.cpp
+++ b/libs/hwui/RenderProperties.cpp
@@ -18,12 +18,12 @@
 
 #include <utils/Trace.h>
 
-#include <SkCanvas.h>
 #include <SkColorFilter.h>
 #include <SkMatrix.h>
 #include <SkPath.h>
 #include <SkPathOps.h>
 
+#include "Canvas.h"
 #include "Matrix.h"
 #include "OpenGLRenderer.h"
 #include "utils/MathUtils.h"
@@ -144,7 +144,7 @@
                     (int)layerBounds.left, (int)layerBounds.top,
                     (int)layerBounds.right, (int)layerBounds.bottom,
                     (int)(mPrimitiveFields.mAlpha * 255),
-                    SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kClipToLayer_SaveFlag);
+                    SaveFlags::HasAlphaLayer | SaveFlags::ClipToLayer);
         }
 
 
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 96c1a7c..20e7c71 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -24,6 +24,7 @@
 #include <SkGraphics.h>
 #include <SkShader.h>
 #include <SkTArray.h>
+#include <SkTLazy.h>
 #include <SkTemplates.h>
 
 #include <memory>
@@ -63,14 +64,14 @@
     virtual bool isHighContrastText() override { return mHighContrastText; }
 
     virtual int getSaveCount() const override;
-    virtual int save(SkCanvas::SaveFlags flags) override;
+    virtual int save(SaveFlags::Flags flags) override;
     virtual void restore() override;
     virtual void restoreToCount(int saveCount) override;
 
     virtual int saveLayer(float left, float top, float right, float bottom,
-                const SkPaint* paint, SkCanvas::SaveFlags flags) override;
+                const SkPaint* paint, SaveFlags::Flags flags) override;
     virtual int saveLayerAlpha(float left, float top, float right, float bottom,
-            int alpha, SkCanvas::SaveFlags flags) override;
+            int alpha, SaveFlags::Flags flags) override;
 
     virtual void getMatrix(SkMatrix* outMatrix) const override;
     virtual void setMatrix(const SkMatrix& matrix) override;
@@ -138,13 +139,13 @@
 
 private:
     struct SaveRec {
-        int                 saveCount;
-        SkCanvas::SaveFlags saveFlags;
+        int              saveCount;
+        SaveFlags::Flags saveFlags;
     };
 
     bool mHighContrastText = false;
 
-    void recordPartialSave(SkCanvas::SaveFlags flags);
+    void recordPartialSave(SaveFlags::Flags flags);
     void saveClipsForFrame(SkTArray<SkClipStack::Element>& clips, int frameSaveCount);
     void applyClips(const SkTArray<SkClipStack::Element>& clips);
 
@@ -231,7 +232,7 @@
     return mCanvas->getSaveCount();
 }
 
-int SkiaCanvas::save(SkCanvas::SaveFlags flags) {
+int SkiaCanvas::save(SaveFlags::Flags flags) {
     int count = mCanvas->save();
     recordPartialSave(flags);
     return count;
@@ -254,8 +255,8 @@
         return;
     }
 
-    bool preserveMatrix = !(rec->saveFlags & SkCanvas::kMatrix_SaveFlag);
-    bool preserveClip   = !(rec->saveFlags & SkCanvas::kClip_SaveFlag);
+    bool preserveMatrix = !(rec->saveFlags & SaveFlags::Matrix);
+    bool preserveClip   = !(rec->saveFlags & SaveFlags::Clip);
 
     SkMatrix savedMatrix;
     if (preserveMatrix) {
@@ -291,34 +292,53 @@
     }
 }
 
+static inline SkCanvas::SaveLayerFlags layerFlags(SaveFlags::Flags flags) {
+    SkCanvas::SaveLayerFlags layerFlags = 0;
+
+    if (!(flags & SaveFlags::HasAlphaLayer)) {
+        layerFlags |= SkCanvas::kIsOpaque_SaveLayerFlag;
+    }
+
+    if (!(flags & SaveFlags::ClipToLayer)) {
+        layerFlags |= SkCanvas::kDontClipToLayer_Legacy_SaveLayerFlag;
+    }
+
+    return layerFlags;
+}
+
 int SkiaCanvas::saveLayer(float left, float top, float right, float bottom,
-            const SkPaint* paint, SkCanvas::SaveFlags flags) {
-    SkRect bounds = SkRect::MakeLTRB(left, top, right, bottom);
-    int count = mCanvas->saveLayer(&bounds, paint, flags | SkCanvas::kMatrixClip_SaveFlag);
+            const SkPaint* paint, SaveFlags::Flags flags) {
+    const SkRect bounds = SkRect::MakeLTRB(left, top, right, bottom);
+    const SkCanvas::SaveLayerRec rec(&bounds, paint, layerFlags(flags));
+
+    int count = mCanvas->saveLayer(rec);
     recordPartialSave(flags);
     return count;
 }
 
 int SkiaCanvas::saveLayerAlpha(float left, float top, float right, float bottom,
-        int alpha, SkCanvas::SaveFlags flags) {
-    SkRect bounds = SkRect::MakeLTRB(left, top, right, bottom);
-    int count = mCanvas->saveLayerAlpha(&bounds, alpha, flags | SkCanvas::kMatrixClip_SaveFlag);
-    recordPartialSave(flags);
-    return count;
+        int alpha, SaveFlags::Flags flags) {
+    SkTLazy<SkPaint> alphaPaint;
+    if (static_cast<unsigned>(alpha) < 0xFF) {
+        alphaPaint.init()->setAlpha(alpha);
+    }
+
+    return this->saveLayer(left, top, right, bottom, alphaPaint.getMaybeNull(),
+                           flags);
 }
 
 // ----------------------------------------------------------------------------
 // functions to emulate legacy SaveFlags (i.e. independent matrix/clip flags)
 // ----------------------------------------------------------------------------
 
-void SkiaCanvas::recordPartialSave(SkCanvas::SaveFlags flags) {
+void SkiaCanvas::recordPartialSave(SaveFlags::Flags flags) {
     // A partial save is a save operation which doesn't capture the full canvas state.
-    // (either kMatrix_SaveFlags or kClip_SaveFlag is missing).
+    // (either SaveFlags::Matrix or SaveFlags::Clip is missing).
 
     // Mask-out non canvas state bits.
-    flags = static_cast<SkCanvas::SaveFlags>(flags & SkCanvas::kMatrixClip_SaveFlag);
+    flags &= SaveFlags::MatrixClip;
 
-    if (SkCanvas::kMatrixClip_SaveFlag == flags) {
+    if (flags == SaveFlags::MatrixClip) {
         // not a partial save.
         return;
     }
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 976f775..6530d4ed8 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -159,7 +159,21 @@
 }
 
 void SkiaCanvasProxy::willSave() {
-    mCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
+    mCanvas->save(android::SaveFlags::MatrixClip);
+}
+
+static inline SaveFlags::Flags saveFlags(SkCanvas::SaveLayerFlags layerFlags) {
+    SaveFlags::Flags saveFlags = 0;
+
+    if (!(layerFlags & SkCanvas::kDontClipToLayer_Legacy_SaveLayerFlag)) {
+        saveFlags |= SaveFlags::ClipToLayer;
+    }
+
+    if (!(layerFlags & SkCanvas::kIsOpaque_SaveLayerFlag)) {
+        saveFlags |= SaveFlags::HasAlphaLayer;
+    }
+
+    return saveFlags;
 }
 
 SkCanvas::SaveLayerStrategy SkiaCanvasProxy::getSaveLayerStrategy(const SaveLayerRec& saveLayerRec) {
@@ -170,7 +184,7 @@
         rect = SkRect::MakeEmpty();
     }
     mCanvas->saveLayer(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, saveLayerRec.fPaint,
-                       (SkCanvas::SaveFlags) SaveLayerFlagsToSaveFlags(saveLayerRec.fSaveLayerFlags));
+                       saveFlags(saveLayerRec.fSaveLayerFlags));
     return SkCanvas::kNoLayer_SaveLayerStrategy;
 }
 
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index c6d8977..27fea1f 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -16,7 +16,7 @@
 
 #include "Snapshot.h"
 
-#include <SkCanvas.h>
+#include "Canvas.h"
 
 namespace android {
 namespace uirenderer {
@@ -57,14 +57,14 @@
         , mClipArea(nullptr)
         , mViewportData(s->mViewportData)
         , mRelativeLightCenter(s->mRelativeLightCenter) {
-    if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
+    if (saveFlags & SaveFlags::Matrix) {
         mTransformRoot = *s->transform;
         transform = &mTransformRoot;
     } else {
         transform = s->transform;
     }
 
-    if (saveFlags & SkCanvas::kClip_SaveFlag) {
+    if (saveFlags & SaveFlags::Clip) {
         mClipAreaRoot = s->getClipArea();
         mClipArea = &mClipAreaRoot;
     } else {
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 5046d37..c09b6dd 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -97,7 +97,7 @@
 
 void Texture::upload(GLint internalformat, uint32_t width, uint32_t height,
         GLenum format, GLenum type, const void* pixels) {
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
     bool needsAlloc = updateSize(width, height, internalformat);
     if (!mId) {
         glGenTextures(1, &mId);
@@ -112,7 +112,7 @@
         glTexSubImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0,
                 format, type, pixels);
     }
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
 }
 
 static void uploadToTexture(bool resize, GLenum format, GLenum type, GLsizei stride, GLsizei bpp,
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 3e20608..1d31c9e 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -420,7 +420,7 @@
         return;
     }
 
-    int saveCount = outCanvas->save(SkCanvas::SaveFlags::kMatrixClip_SaveFlag);
+    int saveCount = outCanvas->save(SaveFlags::MatrixClip);
     outCanvas->translate(mBounds.fLeft, mBounds.fTop);
 
     // Handle RTL mirroring.
diff --git a/libs/hwui/tests/common/nullegl.cpp b/libs/hwui/debug/nullegl.cpp
similarity index 100%
rename from libs/hwui/tests/common/nullegl.cpp
rename to libs/hwui/debug/nullegl.cpp
diff --git a/libs/hwui/tests/common/nullgles.cpp b/libs/hwui/debug/nullgles.cpp
similarity index 99%
rename from libs/hwui/tests/common/nullgles.cpp
rename to libs/hwui/debug/nullgles.cpp
index f8e8c98..ffb0649 100644
--- a/libs/hwui/tests/common/nullgles.cpp
+++ b/libs/hwui/debug/nullgles.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include "unwrap_gles.h"
+
 #include <GLES3/gl3.h>
 #include <GLES2/gl2ext.h>
 
diff --git a/libs/hwui/debug/unwrap_gles.h b/libs/hwui/debug/unwrap_gles.h
new file mode 100644
index 0000000..7716a73
--- /dev/null
+++ b/libs/hwui/debug/unwrap_gles.h
@@ -0,0 +1,918 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef HWUI_GLES_WRAP_ENABLED
+#undef HWUI_GLES_WRAP_ENABLED
+
+#undef glActiveShaderProgram
+#undef glActiveShaderProgramEXT
+#undef glActiveTexture
+#undef glAlphaFunc
+#undef glAlphaFuncQCOM
+#undef glAlphaFuncx
+#undef glAlphaFuncxOES
+#undef glApplyFramebufferAttachmentCMAAINTEL
+#undef glAttachShader
+#undef glBeginConditionalRenderNV
+#undef glBeginPerfMonitorAMD
+#undef glBeginPerfQueryINTEL
+#undef glBeginQuery
+#undef glBeginQueryEXT
+#undef glBeginTransformFeedback
+#undef glBindAttribLocation
+#undef glBindBuffer
+#undef glBindBufferBase
+#undef glBindBufferRange
+#undef glBindFragDataLocationEXT
+#undef glBindFragDataLocationIndexedEXT
+#undef glBindFramebuffer
+#undef glBindFramebufferOES
+#undef glBindImageTexture
+#undef glBindProgramPipeline
+#undef glBindProgramPipelineEXT
+#undef glBindRenderbuffer
+#undef glBindRenderbufferOES
+#undef glBindSampler
+#undef glBindTexture
+#undef glBindTransformFeedback
+#undef glBindVertexArray
+#undef glBindVertexArrayOES
+#undef glBindVertexBuffer
+#undef glBlendBarrier
+#undef glBlendBarrierKHR
+#undef glBlendBarrierNV
+#undef glBlendColor
+#undef glBlendEquation
+#undef glBlendEquationOES
+#undef glBlendEquationSeparate
+#undef glBlendEquationSeparateOES
+#undef glBlendEquationSeparatei
+#undef glBlendEquationSeparateiEXT
+#undef glBlendEquationSeparateiOES
+#undef glBlendEquationi
+#undef glBlendEquationiEXT
+#undef glBlendEquationiOES
+#undef glBlendFunc
+#undef glBlendFuncSeparate
+#undef glBlendFuncSeparateOES
+#undef glBlendFuncSeparatei
+#undef glBlendFuncSeparateiEXT
+#undef glBlendFuncSeparateiOES
+#undef glBlendFunci
+#undef glBlendFunciEXT
+#undef glBlendFunciOES
+#undef glBlendParameteriNV
+#undef glBlitFramebuffer
+#undef glBlitFramebufferANGLE
+#undef glBlitFramebufferNV
+#undef glBufferData
+#undef glBufferStorageEXT
+#undef glBufferSubData
+#undef glCheckFramebufferStatus
+#undef glCheckFramebufferStatusOES
+#undef glClear
+#undef glClearBufferfi
+#undef glClearBufferfv
+#undef glClearBufferiv
+#undef glClearBufferuiv
+#undef glClearColor
+#undef glClearColorx
+#undef glClearColorxOES
+#undef glClearDepthf
+#undef glClearDepthfOES
+#undef glClearDepthx
+#undef glClearDepthxOES
+#undef glClearStencil
+#undef glClientActiveTexture
+#undef glClientWaitSync
+#undef glClientWaitSyncAPPLE
+#undef glClipPlanef
+#undef glClipPlanefIMG
+#undef glClipPlanefOES
+#undef glClipPlanex
+#undef glClipPlanexIMG
+#undef glClipPlanexOES
+#undef glColor4f
+#undef glColor4ub
+#undef glColor4x
+#undef glColor4xOES
+#undef glColorMask
+#undef glColorMaski
+#undef glColorMaskiEXT
+#undef glColorMaskiOES
+#undef glColorPointer
+#undef glCompileShader
+#undef glCompressedTexImage2D
+#undef glCompressedTexImage3D
+#undef glCompressedTexImage3DOES
+#undef glCompressedTexSubImage2D
+#undef glCompressedTexSubImage3D
+#undef glCompressedTexSubImage3DOES
+#undef glCopyBufferSubData
+#undef glCopyBufferSubDataNV
+#undef glCopyImageSubData
+#undef glCopyImageSubDataEXT
+#undef glCopyImageSubDataOES
+#undef glCopyPathNV
+#undef glCopyTexImage2D
+#undef glCopyTexSubImage2D
+#undef glCopyTexSubImage3D
+#undef glCopyTexSubImage3DOES
+#undef glCopyTextureLevelsAPPLE
+#undef glCoverFillPathInstancedNV
+#undef glCoverFillPathNV
+#undef glCoverStrokePathInstancedNV
+#undef glCoverStrokePathNV
+#undef glCoverageMaskNV
+#undef glCoverageModulationNV
+#undef glCoverageModulationTableNV
+#undef glCoverageOperationNV
+#undef glCreatePerfQueryINTEL
+#undef glCreateProgram
+#undef glCreateShader
+#undef glCreateShaderProgramv
+#undef glCreateShaderProgramvEXT
+#undef glCullFace
+#undef glCurrentPaletteMatrixOES
+#undef glDebugMessageCallback
+#undef glDebugMessageCallbackKHR
+#undef glDebugMessageControl
+#undef glDebugMessageControlKHR
+#undef glDebugMessageInsert
+#undef glDebugMessageInsertKHR
+#undef glDeleteBuffers
+#undef glDeleteFencesNV
+#undef glDeleteFramebuffers
+#undef glDeleteFramebuffersOES
+#undef glDeletePathsNV
+#undef glDeletePerfMonitorsAMD
+#undef glDeletePerfQueryINTEL
+#undef glDeleteProgram
+#undef glDeleteProgramPipelines
+#undef glDeleteProgramPipelinesEXT
+#undef glDeleteQueries
+#undef glDeleteQueriesEXT
+#undef glDeleteRenderbuffers
+#undef glDeleteRenderbuffersOES
+#undef glDeleteSamplers
+#undef glDeleteShader
+#undef glDeleteSync
+#undef glDeleteSyncAPPLE
+#undef glDeleteTextures
+#undef glDeleteTransformFeedbacks
+#undef glDeleteVertexArrays
+#undef glDeleteVertexArraysOES
+#undef glDepthFunc
+#undef glDepthMask
+#undef glDepthRangeArrayfvNV
+#undef glDepthRangeIndexedfNV
+#undef glDepthRangef
+#undef glDepthRangefOES
+#undef glDepthRangex
+#undef glDepthRangexOES
+#undef glDetachShader
+#undef glDisable
+#undef glDisableClientState
+#undef glDisableDriverControlQCOM
+#undef glDisableVertexAttribArray
+#undef glDisablei
+#undef glDisableiEXT
+#undef glDisableiNV
+#undef glDisableiOES
+#undef glDiscardFramebufferEXT
+#undef glDispatchCompute
+#undef glDispatchComputeIndirect
+#undef glDrawArrays
+#undef glDrawArraysIndirect
+#undef glDrawArraysInstanced
+#undef glDrawArraysInstancedANGLE
+#undef glDrawArraysInstancedBaseInstanceEXT
+#undef glDrawArraysInstancedEXT
+#undef glDrawArraysInstancedNV
+#undef glDrawBuffers
+#undef glDrawBuffersEXT
+#undef glDrawBuffersIndexedEXT
+#undef glDrawBuffersNV
+#undef glDrawElements
+#undef glDrawElementsBaseVertex
+#undef glDrawElementsBaseVertexEXT
+#undef glDrawElementsBaseVertexOES
+#undef glDrawElementsIndirect
+#undef glDrawElementsInstanced
+#undef glDrawElementsInstancedANGLE
+#undef glDrawElementsInstancedBaseInstanceEXT
+#undef glDrawElementsInstancedBaseVertex
+#undef glDrawElementsInstancedBaseVertexBaseInstanceEXT
+#undef glDrawElementsInstancedBaseVertexEXT
+#undef glDrawElementsInstancedBaseVertexOES
+#undef glDrawElementsInstancedEXT
+#undef glDrawElementsInstancedNV
+#undef glDrawRangeElements
+#undef glDrawRangeElementsBaseVertex
+#undef glDrawRangeElementsBaseVertexEXT
+#undef glDrawRangeElementsBaseVertexOES
+#undef glDrawTexfOES
+#undef glDrawTexfvOES
+#undef glDrawTexiOES
+#undef glDrawTexivOES
+#undef glDrawTexsOES
+#undef glDrawTexsvOES
+#undef glDrawTexxOES
+#undef glDrawTexxvOES
+#undef glEGLImageTargetRenderbufferStorageOES
+#undef glEGLImageTargetTexture2DOES
+#undef glEnable
+#undef glEnableClientState
+#undef glEnableDriverControlQCOM
+#undef glEnableVertexAttribArray
+#undef glEnablei
+#undef glEnableiEXT
+#undef glEnableiNV
+#undef glEnableiOES
+#undef glEndConditionalRenderNV
+#undef glEndPerfMonitorAMD
+#undef glEndPerfQueryINTEL
+#undef glEndQuery
+#undef glEndQueryEXT
+#undef glEndTilingQCOM
+#undef glEndTransformFeedback
+#undef glExtGetBufferPointervQCOM
+#undef glExtGetBuffersQCOM
+#undef glExtGetFramebuffersQCOM
+#undef glExtGetProgramBinarySourceQCOM
+#undef glExtGetProgramsQCOM
+#undef glExtGetRenderbuffersQCOM
+#undef glExtGetShadersQCOM
+#undef glExtGetTexLevelParameterivQCOM
+#undef glExtGetTexSubImageQCOM
+#undef glExtGetTexturesQCOM
+#undef glExtIsProgramBinaryQCOM
+#undef glExtTexObjectStateOverrideiQCOM
+#undef glFenceSync
+#undef glFenceSyncAPPLE
+#undef glFinish
+#undef glFinishFenceNV
+#undef glFlush
+#undef glFlushMappedBufferRange
+#undef glFlushMappedBufferRangeEXT
+#undef glFogf
+#undef glFogfv
+#undef glFogx
+#undef glFogxOES
+#undef glFogxv
+#undef glFogxvOES
+#undef glFragmentCoverageColorNV
+#undef glFramebufferParameteri
+#undef glFramebufferRenderbuffer
+#undef glFramebufferRenderbufferOES
+#undef glFramebufferSampleLocationsfvNV
+#undef glFramebufferTexture
+#undef glFramebufferTexture2D
+#undef glFramebufferTexture2DMultisampleEXT
+#undef glFramebufferTexture2DMultisampleIMG
+#undef glFramebufferTexture2DOES
+#undef glFramebufferTexture3DOES
+#undef glFramebufferTextureEXT
+#undef glFramebufferTextureLayer
+#undef glFramebufferTextureMultisampleMultiviewOVR
+#undef glFramebufferTextureMultiviewOVR
+#undef glFramebufferTextureOES
+#undef glFrontFace
+#undef glFrustumf
+#undef glFrustumfOES
+#undef glFrustumx
+#undef glFrustumxOES
+#undef glGenBuffers
+#undef glGenFencesNV
+#undef glGenFramebuffers
+#undef glGenFramebuffersOES
+#undef glGenPathsNV
+#undef glGenPerfMonitorsAMD
+#undef glGenProgramPipelines
+#undef glGenProgramPipelinesEXT
+#undef glGenQueries
+#undef glGenQueriesEXT
+#undef glGenRenderbuffers
+#undef glGenRenderbuffersOES
+#undef glGenSamplers
+#undef glGenTextures
+#undef glGenTransformFeedbacks
+#undef glGenVertexArrays
+#undef glGenVertexArraysOES
+#undef glGenerateMipmap
+#undef glGenerateMipmapOES
+#undef glGetActiveAttrib
+#undef glGetActiveUniform
+#undef glGetActiveUniformBlockName
+#undef glGetActiveUniformBlockiv
+#undef glGetActiveUniformsiv
+#undef glGetAttachedShaders
+#undef glGetAttribLocation
+#undef glGetBooleani_v
+#undef glGetBooleanv
+#undef glGetBufferParameteri64v
+#undef glGetBufferParameteriv
+#undef glGetBufferPointerv
+#undef glGetBufferPointervOES
+#undef glGetClipPlanef
+#undef glGetClipPlanefOES
+#undef glGetClipPlanex
+#undef glGetClipPlanexOES
+#undef glGetCoverageModulationTableNV
+#undef glGetDebugMessageLog
+#undef glGetDebugMessageLogKHR
+#undef glGetDriverControlStringQCOM
+#undef glGetDriverControlsQCOM
+#undef glGetError
+#undef glGetFenceivNV
+#undef glGetFirstPerfQueryIdINTEL
+#undef glGetFixedv
+#undef glGetFixedvOES
+#undef glGetFloati_vNV
+#undef glGetFloatv
+#undef glGetFragDataIndexEXT
+#undef glGetFragDataLocation
+#undef glGetFramebufferAttachmentParameteriv
+#undef glGetFramebufferAttachmentParameterivOES
+#undef glGetFramebufferParameteriv
+#undef glGetGraphicsResetStatus
+#undef glGetGraphicsResetStatusEXT
+#undef glGetGraphicsResetStatusKHR
+#undef glGetImageHandleNV
+#undef glGetInteger64i_v
+#undef glGetInteger64v
+#undef glGetInteger64vAPPLE
+#undef glGetIntegeri_v
+#undef glGetIntegeri_vEXT
+#undef glGetIntegerv
+#undef glGetInternalformatSampleivNV
+#undef glGetInternalformativ
+#undef glGetLightfv
+#undef glGetLightxv
+#undef glGetLightxvOES
+#undef glGetMaterialfv
+#undef glGetMaterialxv
+#undef glGetMaterialxvOES
+#undef glGetMultisamplefv
+#undef glGetNextPerfQueryIdINTEL
+#undef glGetObjectLabel
+#undef glGetObjectLabelEXT
+#undef glGetObjectLabelKHR
+#undef glGetObjectPtrLabel
+#undef glGetObjectPtrLabelKHR
+#undef glGetPathCommandsNV
+#undef glGetPathCoordsNV
+#undef glGetPathDashArrayNV
+#undef glGetPathLengthNV
+#undef glGetPathMetricRangeNV
+#undef glGetPathMetricsNV
+#undef glGetPathParameterfvNV
+#undef glGetPathParameterivNV
+#undef glGetPathSpacingNV
+#undef glGetPerfCounterInfoINTEL
+#undef glGetPerfMonitorCounterDataAMD
+#undef glGetPerfMonitorCounterInfoAMD
+#undef glGetPerfMonitorCounterStringAMD
+#undef glGetPerfMonitorCountersAMD
+#undef glGetPerfMonitorGroupStringAMD
+#undef glGetPerfMonitorGroupsAMD
+#undef glGetPerfQueryDataINTEL
+#undef glGetPerfQueryIdByNameINTEL
+#undef glGetPerfQueryInfoINTEL
+#undef glGetPointerv
+#undef glGetPointervKHR
+#undef glGetProgramBinary
+#undef glGetProgramBinaryOES
+#undef glGetProgramInfoLog
+#undef glGetProgramInterfaceiv
+#undef glGetProgramPipelineInfoLog
+#undef glGetProgramPipelineInfoLogEXT
+#undef glGetProgramPipelineiv
+#undef glGetProgramPipelineivEXT
+#undef glGetProgramResourceIndex
+#undef glGetProgramResourceLocation
+#undef glGetProgramResourceLocationIndexEXT
+#undef glGetProgramResourceName
+#undef glGetProgramResourcefvNV
+#undef glGetProgramResourceiv
+#undef glGetProgramiv
+#undef glGetQueryObjecti64vEXT
+#undef glGetQueryObjectivEXT
+#undef glGetQueryObjectui64vEXT
+#undef glGetQueryObjectuiv
+#undef glGetQueryObjectuivEXT
+#undef glGetQueryiv
+#undef glGetQueryivEXT
+#undef glGetRenderbufferParameteriv
+#undef glGetRenderbufferParameterivOES
+#undef glGetSamplerParameterIiv
+#undef glGetSamplerParameterIivEXT
+#undef glGetSamplerParameterIivOES
+#undef glGetSamplerParameterIuiv
+#undef glGetSamplerParameterIuivEXT
+#undef glGetSamplerParameterIuivOES
+#undef glGetSamplerParameterfv
+#undef glGetSamplerParameteriv
+#undef glGetShaderInfoLog
+#undef glGetShaderPrecisionFormat
+#undef glGetShaderSource
+#undef glGetShaderiv
+#undef glGetString
+#undef glGetStringi
+#undef glGetSynciv
+#undef glGetSyncivAPPLE
+#undef glGetTexEnvfv
+#undef glGetTexEnviv
+#undef glGetTexEnvxv
+#undef glGetTexEnvxvOES
+#undef glGetTexGenfvOES
+#undef glGetTexGenivOES
+#undef glGetTexGenxvOES
+#undef glGetTexLevelParameterfv
+#undef glGetTexLevelParameteriv
+#undef glGetTexParameterIiv
+#undef glGetTexParameterIivEXT
+#undef glGetTexParameterIivOES
+#undef glGetTexParameterIuiv
+#undef glGetTexParameterIuivEXT
+#undef glGetTexParameterIuivOES
+#undef glGetTexParameterfv
+#undef glGetTexParameteriv
+#undef glGetTexParameterxv
+#undef glGetTexParameterxvOES
+#undef glGetTextureHandleNV
+#undef glGetTextureSamplerHandleNV
+#undef glGetTransformFeedbackVarying
+#undef glGetTranslatedShaderSourceANGLE
+#undef glGetUniformBlockIndex
+#undef glGetUniformIndices
+#undef glGetUniformLocation
+#undef glGetUniformfv
+#undef glGetUniformiv
+#undef glGetUniformuiv
+#undef glGetVertexAttribIiv
+#undef glGetVertexAttribIuiv
+#undef glGetVertexAttribPointerv
+#undef glGetVertexAttribfv
+#undef glGetVertexAttribiv
+#undef glGetnUniformfv
+#undef glGetnUniformfvEXT
+#undef glGetnUniformfvKHR
+#undef glGetnUniformiv
+#undef glGetnUniformivEXT
+#undef glGetnUniformivKHR
+#undef glGetnUniformuiv
+#undef glGetnUniformuivKHR
+#undef glHint
+#undef glInsertEventMarkerEXT
+#undef glInterpolatePathsNV
+#undef glInvalidateFramebuffer
+#undef glInvalidateSubFramebuffer
+#undef glIsBuffer
+#undef glIsEnabled
+#undef glIsEnabledi
+#undef glIsEnablediEXT
+#undef glIsEnablediNV
+#undef glIsEnablediOES
+#undef glIsFenceNV
+#undef glIsFramebuffer
+#undef glIsFramebufferOES
+#undef glIsImageHandleResidentNV
+#undef glIsPathNV
+#undef glIsPointInFillPathNV
+#undef glIsPointInStrokePathNV
+#undef glIsProgram
+#undef glIsProgramPipeline
+#undef glIsProgramPipelineEXT
+#undef glIsQuery
+#undef glIsQueryEXT
+#undef glIsRenderbuffer
+#undef glIsRenderbufferOES
+#undef glIsSampler
+#undef glIsShader
+#undef glIsSync
+#undef glIsSyncAPPLE
+#undef glIsTexture
+#undef glIsTextureHandleResidentNV
+#undef glIsTransformFeedback
+#undef glIsVertexArray
+#undef glIsVertexArrayOES
+#undef glLabelObjectEXT
+#undef glLightModelf
+#undef glLightModelfv
+#undef glLightModelx
+#undef glLightModelxOES
+#undef glLightModelxv
+#undef glLightModelxvOES
+#undef glLightf
+#undef glLightfv
+#undef glLightx
+#undef glLightxOES
+#undef glLightxv
+#undef glLightxvOES
+#undef glLineWidth
+#undef glLineWidthx
+#undef glLineWidthxOES
+#undef glLinkProgram
+#undef glLoadIdentity
+#undef glLoadMatrixf
+#undef glLoadMatrixx
+#undef glLoadMatrixxOES
+#undef glLoadPaletteFromModelViewMatrixOES
+#undef glLogicOp
+#undef glMakeImageHandleNonResidentNV
+#undef glMakeImageHandleResidentNV
+#undef glMakeTextureHandleNonResidentNV
+#undef glMakeTextureHandleResidentNV
+#undef glMapBufferOES
+#undef glMapBufferRange
+#undef glMapBufferRangeEXT
+#undef glMaterialf
+#undef glMaterialfv
+#undef glMaterialx
+#undef glMaterialxOES
+#undef glMaterialxv
+#undef glMaterialxvOES
+#undef glMatrixIndexPointerOES
+#undef glMatrixLoad3x2fNV
+#undef glMatrixLoad3x3fNV
+#undef glMatrixLoadTranspose3x3fNV
+#undef glMatrixMode
+#undef glMatrixMult3x2fNV
+#undef glMatrixMult3x3fNV
+#undef glMatrixMultTranspose3x3fNV
+#undef glMemoryBarrier
+#undef glMemoryBarrierByRegion
+#undef glMinSampleShading
+#undef glMinSampleShadingOES
+#undef glMultMatrixf
+#undef glMultMatrixx
+#undef glMultMatrixxOES
+#undef glMultiDrawArraysEXT
+#undef glMultiDrawArraysIndirectEXT
+#undef glMultiDrawElementsBaseVertexEXT
+#undef glMultiDrawElementsBaseVertexOES
+#undef glMultiDrawElementsEXT
+#undef glMultiDrawElementsIndirectEXT
+#undef glMultiTexCoord4f
+#undef glMultiTexCoord4x
+#undef glMultiTexCoord4xOES
+#undef glNamedFramebufferSampleLocationsfvNV
+#undef glNormal3f
+#undef glNormal3x
+#undef glNormal3xOES
+#undef glNormalPointer
+#undef glObjectLabel
+#undef glObjectLabelKHR
+#undef glObjectPtrLabel
+#undef glObjectPtrLabelKHR
+#undef glOrthof
+#undef glOrthofOES
+#undef glOrthox
+#undef glOrthoxOES
+#undef glPatchParameteri
+#undef glPatchParameteriEXT
+#undef glPatchParameteriOES
+#undef glPathCommandsNV
+#undef glPathCoordsNV
+#undef glPathCoverDepthFuncNV
+#undef glPathDashArrayNV
+#undef glPathGlyphIndexArrayNV
+#undef glPathGlyphIndexRangeNV
+#undef glPathGlyphRangeNV
+#undef glPathGlyphsNV
+#undef glPathMemoryGlyphIndexArrayNV
+#undef glPathParameterfNV
+#undef glPathParameterfvNV
+#undef glPathParameteriNV
+#undef glPathParameterivNV
+#undef glPathStencilDepthOffsetNV
+#undef glPathStencilFuncNV
+#undef glPathStringNV
+#undef glPathSubCommandsNV
+#undef glPathSubCoordsNV
+#undef glPauseTransformFeedback
+#undef glPixelStorei
+#undef glPointAlongPathNV
+#undef glPointParameterf
+#undef glPointParameterfv
+#undef glPointParameterx
+#undef glPointParameterxOES
+#undef glPointParameterxv
+#undef glPointParameterxvOES
+#undef glPointSize
+#undef glPointSizePointerOES
+#undef glPointSizex
+#undef glPointSizexOES
+#undef glPolygonModeNV
+#undef glPolygonOffset
+#undef glPolygonOffsetx
+#undef glPolygonOffsetxOES
+#undef glPopDebugGroup
+#undef glPopDebugGroupKHR
+#undef glPopGroupMarkerEXT
+#undef glPopMatrix
+#undef glPrimitiveBoundingBox
+#undef glPrimitiveBoundingBoxEXT
+#undef glPrimitiveBoundingBoxOES
+#undef glProgramBinary
+#undef glProgramBinaryOES
+#undef glProgramParameteri
+#undef glProgramParameteriEXT
+#undef glProgramPathFragmentInputGenNV
+#undef glProgramUniform1f
+#undef glProgramUniform1fEXT
+#undef glProgramUniform1fv
+#undef glProgramUniform1fvEXT
+#undef glProgramUniform1i
+#undef glProgramUniform1iEXT
+#undef glProgramUniform1iv
+#undef glProgramUniform1ivEXT
+#undef glProgramUniform1ui
+#undef glProgramUniform1uiEXT
+#undef glProgramUniform1uiv
+#undef glProgramUniform1uivEXT
+#undef glProgramUniform2f
+#undef glProgramUniform2fEXT
+#undef glProgramUniform2fv
+#undef glProgramUniform2fvEXT
+#undef glProgramUniform2i
+#undef glProgramUniform2iEXT
+#undef glProgramUniform2iv
+#undef glProgramUniform2ivEXT
+#undef glProgramUniform2ui
+#undef glProgramUniform2uiEXT
+#undef glProgramUniform2uiv
+#undef glProgramUniform2uivEXT
+#undef glProgramUniform3f
+#undef glProgramUniform3fEXT
+#undef glProgramUniform3fv
+#undef glProgramUniform3fvEXT
+#undef glProgramUniform3i
+#undef glProgramUniform3iEXT
+#undef glProgramUniform3iv
+#undef glProgramUniform3ivEXT
+#undef glProgramUniform3ui
+#undef glProgramUniform3uiEXT
+#undef glProgramUniform3uiv
+#undef glProgramUniform3uivEXT
+#undef glProgramUniform4f
+#undef glProgramUniform4fEXT
+#undef glProgramUniform4fv
+#undef glProgramUniform4fvEXT
+#undef glProgramUniform4i
+#undef glProgramUniform4iEXT
+#undef glProgramUniform4iv
+#undef glProgramUniform4ivEXT
+#undef glProgramUniform4ui
+#undef glProgramUniform4uiEXT
+#undef glProgramUniform4uiv
+#undef glProgramUniform4uivEXT
+#undef glProgramUniformHandleui64NV
+#undef glProgramUniformHandleui64vNV
+#undef glProgramUniformMatrix2fv
+#undef glProgramUniformMatrix2fvEXT
+#undef glProgramUniformMatrix2x3fv
+#undef glProgramUniformMatrix2x3fvEXT
+#undef glProgramUniformMatrix2x4fv
+#undef glProgramUniformMatrix2x4fvEXT
+#undef glProgramUniformMatrix3fv
+#undef glProgramUniformMatrix3fvEXT
+#undef glProgramUniformMatrix3x2fv
+#undef glProgramUniformMatrix3x2fvEXT
+#undef glProgramUniformMatrix3x4fv
+#undef glProgramUniformMatrix3x4fvEXT
+#undef glProgramUniformMatrix4fv
+#undef glProgramUniformMatrix4fvEXT
+#undef glProgramUniformMatrix4x2fv
+#undef glProgramUniformMatrix4x2fvEXT
+#undef glProgramUniformMatrix4x3fv
+#undef glProgramUniformMatrix4x3fvEXT
+#undef glPushDebugGroup
+#undef glPushDebugGroupKHR
+#undef glPushGroupMarkerEXT
+#undef glPushMatrix
+#undef glQueryCounterEXT
+#undef glQueryMatrixxOES
+#undef glRasterSamplesEXT
+#undef glReadBuffer
+#undef glReadBufferIndexedEXT
+#undef glReadBufferNV
+#undef glReadPixels
+#undef glReadnPixels
+#undef glReadnPixelsEXT
+#undef glReadnPixelsKHR
+#undef glReleaseShaderCompiler
+#undef glRenderbufferStorage
+#undef glRenderbufferStorageMultisample
+#undef glRenderbufferStorageMultisampleANGLE
+#undef glRenderbufferStorageMultisampleAPPLE
+#undef glRenderbufferStorageMultisampleEXT
+#undef glRenderbufferStorageMultisampleIMG
+#undef glRenderbufferStorageMultisampleNV
+#undef glRenderbufferStorageOES
+#undef glResolveDepthValuesNV
+#undef glResolveMultisampleFramebufferAPPLE
+#undef glResumeTransformFeedback
+#undef glRotatef
+#undef glRotatex
+#undef glRotatexOES
+#undef glSampleCoverage
+#undef glSampleCoveragex
+#undef glSampleCoveragexOES
+#undef glSampleMaski
+#undef glSamplerParameterIiv
+#undef glSamplerParameterIivEXT
+#undef glSamplerParameterIivOES
+#undef glSamplerParameterIuiv
+#undef glSamplerParameterIuivEXT
+#undef glSamplerParameterIuivOES
+#undef glSamplerParameterf
+#undef glSamplerParameterfv
+#undef glSamplerParameteri
+#undef glSamplerParameteriv
+#undef glScalef
+#undef glScalex
+#undef glScalexOES
+#undef glScissor
+#undef glScissorArrayvNV
+#undef glScissorIndexedNV
+#undef glScissorIndexedvNV
+#undef glSelectPerfMonitorCountersAMD
+#undef glSetFenceNV
+#undef glShadeModel
+#undef glShaderBinary
+#undef glShaderSource
+#undef glStartTilingQCOM
+#undef glStencilFillPathInstancedNV
+#undef glStencilFillPathNV
+#undef glStencilFunc
+#undef glStencilFuncSeparate
+#undef glStencilMask
+#undef glStencilMaskSeparate
+#undef glStencilOp
+#undef glStencilOpSeparate
+#undef glStencilStrokePathInstancedNV
+#undef glStencilStrokePathNV
+#undef glStencilThenCoverFillPathInstancedNV
+#undef glStencilThenCoverFillPathNV
+#undef glStencilThenCoverStrokePathInstancedNV
+#undef glStencilThenCoverStrokePathNV
+#undef glSubpixelPrecisionBiasNV
+#undef glTestFenceNV
+#undef glTexBuffer
+#undef glTexBufferEXT
+#undef glTexBufferOES
+#undef glTexBufferRange
+#undef glTexBufferRangeEXT
+#undef glTexBufferRangeOES
+#undef glTexCoordPointer
+#undef glTexEnvf
+#undef glTexEnvfv
+#undef glTexEnvi
+#undef glTexEnviv
+#undef glTexEnvx
+#undef glTexEnvxOES
+#undef glTexEnvxv
+#undef glTexEnvxvOES
+#undef glTexGenfOES
+#undef glTexGenfvOES
+#undef glTexGeniOES
+#undef glTexGenivOES
+#undef glTexGenxOES
+#undef glTexGenxvOES
+#undef glTexImage2D
+#undef glTexImage3D
+#undef glTexImage3DOES
+#undef glTexPageCommitmentEXT
+#undef glTexParameterIiv
+#undef glTexParameterIivEXT
+#undef glTexParameterIivOES
+#undef glTexParameterIuiv
+#undef glTexParameterIuivEXT
+#undef glTexParameterIuivOES
+#undef glTexParameterf
+#undef glTexParameterfv
+#undef glTexParameteri
+#undef glTexParameteriv
+#undef glTexParameterx
+#undef glTexParameterxOES
+#undef glTexParameterxv
+#undef glTexParameterxvOES
+#undef glTexStorage1DEXT
+#undef glTexStorage2D
+#undef glTexStorage2DEXT
+#undef glTexStorage2DMultisample
+#undef glTexStorage3D
+#undef glTexStorage3DEXT
+#undef glTexStorage3DMultisample
+#undef glTexStorage3DMultisampleOES
+#undef glTexSubImage2D
+#undef glTexSubImage3D
+#undef glTexSubImage3DOES
+#undef glTextureStorage1DEXT
+#undef glTextureStorage2DEXT
+#undef glTextureStorage3DEXT
+#undef glTextureViewEXT
+#undef glTextureViewOES
+#undef glTransformFeedbackVaryings
+#undef glTransformPathNV
+#undef glTranslatef
+#undef glTranslatex
+#undef glTranslatexOES
+#undef glUniform1f
+#undef glUniform1fv
+#undef glUniform1i
+#undef glUniform1iv
+#undef glUniform1ui
+#undef glUniform1uiv
+#undef glUniform2f
+#undef glUniform2fv
+#undef glUniform2i
+#undef glUniform2iv
+#undef glUniform2ui
+#undef glUniform2uiv
+#undef glUniform3f
+#undef glUniform3fv
+#undef glUniform3i
+#undef glUniform3iv
+#undef glUniform3ui
+#undef glUniform3uiv
+#undef glUniform4f
+#undef glUniform4fv
+#undef glUniform4i
+#undef glUniform4iv
+#undef glUniform4ui
+#undef glUniform4uiv
+#undef glUniformBlockBinding
+#undef glUniformHandleui64NV
+#undef glUniformHandleui64vNV
+#undef glUniformMatrix2fv
+#undef glUniformMatrix2x3fv
+#undef glUniformMatrix2x3fvNV
+#undef glUniformMatrix2x4fv
+#undef glUniformMatrix2x4fvNV
+#undef glUniformMatrix3fv
+#undef glUniformMatrix3x2fv
+#undef glUniformMatrix3x2fvNV
+#undef glUniformMatrix3x4fv
+#undef glUniformMatrix3x4fvNV
+#undef glUniformMatrix4fv
+#undef glUniformMatrix4x2fv
+#undef glUniformMatrix4x2fvNV
+#undef glUniformMatrix4x3fv
+#undef glUniformMatrix4x3fvNV
+#undef glUnmapBuffer
+#undef glUnmapBufferOES
+#undef glUseProgram
+#undef glUseProgramStages
+#undef glUseProgramStagesEXT
+#undef glValidateProgram
+#undef glValidateProgramPipeline
+#undef glValidateProgramPipelineEXT
+#undef glVertexAttrib1f
+#undef glVertexAttrib1fv
+#undef glVertexAttrib2f
+#undef glVertexAttrib2fv
+#undef glVertexAttrib3f
+#undef glVertexAttrib3fv
+#undef glVertexAttrib4f
+#undef glVertexAttrib4fv
+#undef glVertexAttribBinding
+#undef glVertexAttribDivisor
+#undef glVertexAttribDivisorANGLE
+#undef glVertexAttribDivisorEXT
+#undef glVertexAttribDivisorNV
+#undef glVertexAttribFormat
+#undef glVertexAttribI4i
+#undef glVertexAttribI4iv
+#undef glVertexAttribI4ui
+#undef glVertexAttribI4uiv
+#undef glVertexAttribIFormat
+#undef glVertexAttribIPointer
+#undef glVertexAttribPointer
+#undef glVertexBindingDivisor
+#undef glVertexPointer
+#undef glViewport
+#undef glViewportArrayvNV
+#undef glViewportIndexedfNV
+#undef glViewportIndexedfvNV
+#undef glWaitSync
+#undef glWaitSyncAPPLE
+#undef glWeightPathsNV
+#undef glWeightPointerOES
+
+#endif // HWUI_GLES_WRAP_ENABLED
diff --git a/libs/hwui/debug/wrap_gles.cpp b/libs/hwui/debug/wrap_gles.cpp
new file mode 100644
index 0000000..c4f2e35
--- /dev/null
+++ b/libs/hwui/debug/wrap_gles.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 "unwrap_gles.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+#include <GLES3/gl31.h>
+#include <GLES3/gl32.h>
+
+#include <cutils/log.h>
+
+void assertNoGlErrors(const char* apicall) {
+    GLenum status = GL_NO_ERROR;
+    GLenum lastError = GL_NO_ERROR;
+    const char* lastErrorName = nullptr;
+    while ((status = glGetError()) != GL_NO_ERROR) {
+        lastError = status;
+        switch (status) {
+        case GL_INVALID_ENUM:
+            ALOGE("GL error:  GL_INVALID_ENUM");
+            lastErrorName = "GL_INVALID_ENUM";
+            break;
+        case GL_INVALID_VALUE:
+            ALOGE("GL error:  GL_INVALID_VALUE");
+            lastErrorName = "GL_INVALID_VALUE";
+            break;
+        case GL_INVALID_OPERATION:
+            ALOGE("GL error:  GL_INVALID_OPERATION");
+            lastErrorName = "GL_INVALID_OPERATION";
+            break;
+        case GL_OUT_OF_MEMORY:
+            ALOGE("GL error:  Out of memory!");
+            lastErrorName = "GL_OUT_OF_MEMORY";
+            break;
+        default:
+            ALOGE("GL error: 0x%x", status);
+            lastErrorName = "UNKNOWN";
+        }
+    }
+    LOG_ALWAYS_FATAL_IF(lastError != GL_NO_ERROR,
+            "%s error! %s (0x%x)", apicall, lastErrorName, lastError);
+}
+
+#define API_ENTRY(x) wrap_##x
+#define CALL_GL_API(x, ...) x(__VA_ARGS__); assertNoGlErrors(#x)
+#define CALL_GL_API_RETURN(x, ...) auto ret = x(__VA_ARGS__);\
+    assertNoGlErrors(#x);\
+    return ret
+
+extern "C" {
+#include <gl2_api.in>
+#include <gl2ext_api.in>
+
+// libGLESv2 handles these specially, so they are not in gl2_api.in
+
+void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean *data) {
+    CALL_GL_API(glGetBooleanv, pname, data);
+}
+void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat *data) {
+    CALL_GL_API(glGetFloatv, pname, data);
+}
+void API_ENTRY(glGetIntegerv)(GLenum pname, GLint *data) {
+    CALL_GL_API(glGetIntegerv, pname, data);
+}
+const GLubyte * API_ENTRY(glGetString)(GLenum name) {
+    CALL_GL_API_RETURN(glGetString, name);
+}
+const GLubyte * API_ENTRY(glGetStringi)(GLenum name, GLuint index) {
+    CALL_GL_API_RETURN(glGetStringi, name, index);
+}
+void API_ENTRY(glGetInteger64v)(GLenum pname, GLint64 *data) {
+    CALL_GL_API(glGetInteger64v, pname, data);
+}
+}
diff --git a/libs/hwui/debug/wrap_gles.h b/libs/hwui/debug/wrap_gles.h
new file mode 100644
index 0000000..4a35374
--- /dev/null
+++ b/libs/hwui/debug/wrap_gles.h
@@ -0,0 +1,918 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 HWUI_GLES_WRAP_ENABLED
+#define HWUI_GLES_WRAP_ENABLED
+
+#define glActiveShaderProgram wrap_glActiveShaderProgram
+#define glActiveShaderProgramEXT wrap_glActiveShaderProgramEXT
+#define glActiveTexture wrap_glActiveTexture
+#define glAlphaFunc wrap_glAlphaFunc
+#define glAlphaFuncQCOM wrap_glAlphaFuncQCOM
+#define glAlphaFuncx wrap_glAlphaFuncx
+#define glAlphaFuncxOES wrap_glAlphaFuncxOES
+#define glApplyFramebufferAttachmentCMAAINTEL wrap_glApplyFramebufferAttachmentCMAAINTEL
+#define glAttachShader wrap_glAttachShader
+#define glBeginConditionalRenderNV wrap_glBeginConditionalRenderNV
+#define glBeginPerfMonitorAMD wrap_glBeginPerfMonitorAMD
+#define glBeginPerfQueryINTEL wrap_glBeginPerfQueryINTEL
+#define glBeginQuery wrap_glBeginQuery
+#define glBeginQueryEXT wrap_glBeginQueryEXT
+#define glBeginTransformFeedback wrap_glBeginTransformFeedback
+#define glBindAttribLocation wrap_glBindAttribLocation
+#define glBindBuffer wrap_glBindBuffer
+#define glBindBufferBase wrap_glBindBufferBase
+#define glBindBufferRange wrap_glBindBufferRange
+#define glBindFragDataLocationEXT wrap_glBindFragDataLocationEXT
+#define glBindFragDataLocationIndexedEXT wrap_glBindFragDataLocationIndexedEXT
+#define glBindFramebuffer wrap_glBindFramebuffer
+#define glBindFramebufferOES wrap_glBindFramebufferOES
+#define glBindImageTexture wrap_glBindImageTexture
+#define glBindProgramPipeline wrap_glBindProgramPipeline
+#define glBindProgramPipelineEXT wrap_glBindProgramPipelineEXT
+#define glBindRenderbuffer wrap_glBindRenderbuffer
+#define glBindRenderbufferOES wrap_glBindRenderbufferOES
+#define glBindSampler wrap_glBindSampler
+#define glBindTexture wrap_glBindTexture
+#define glBindTransformFeedback wrap_glBindTransformFeedback
+#define glBindVertexArray wrap_glBindVertexArray
+#define glBindVertexArrayOES wrap_glBindVertexArrayOES
+#define glBindVertexBuffer wrap_glBindVertexBuffer
+#define glBlendBarrier wrap_glBlendBarrier
+#define glBlendBarrierKHR wrap_glBlendBarrierKHR
+#define glBlendBarrierNV wrap_glBlendBarrierNV
+#define glBlendColor wrap_glBlendColor
+#define glBlendEquation wrap_glBlendEquation
+#define glBlendEquationOES wrap_glBlendEquationOES
+#define glBlendEquationSeparate wrap_glBlendEquationSeparate
+#define glBlendEquationSeparateOES wrap_glBlendEquationSeparateOES
+#define glBlendEquationSeparatei wrap_glBlendEquationSeparatei
+#define glBlendEquationSeparateiEXT wrap_glBlendEquationSeparateiEXT
+#define glBlendEquationSeparateiOES wrap_glBlendEquationSeparateiOES
+#define glBlendEquationi wrap_glBlendEquationi
+#define glBlendEquationiEXT wrap_glBlendEquationiEXT
+#define glBlendEquationiOES wrap_glBlendEquationiOES
+#define glBlendFunc wrap_glBlendFunc
+#define glBlendFuncSeparate wrap_glBlendFuncSeparate
+#define glBlendFuncSeparateOES wrap_glBlendFuncSeparateOES
+#define glBlendFuncSeparatei wrap_glBlendFuncSeparatei
+#define glBlendFuncSeparateiEXT wrap_glBlendFuncSeparateiEXT
+#define glBlendFuncSeparateiOES wrap_glBlendFuncSeparateiOES
+#define glBlendFunci wrap_glBlendFunci
+#define glBlendFunciEXT wrap_glBlendFunciEXT
+#define glBlendFunciOES wrap_glBlendFunciOES
+#define glBlendParameteriNV wrap_glBlendParameteriNV
+#define glBlitFramebuffer wrap_glBlitFramebuffer
+#define glBlitFramebufferANGLE wrap_glBlitFramebufferANGLE
+#define glBlitFramebufferNV wrap_glBlitFramebufferNV
+#define glBufferData wrap_glBufferData
+#define glBufferStorageEXT wrap_glBufferStorageEXT
+#define glBufferSubData wrap_glBufferSubData
+#define glCheckFramebufferStatus wrap_glCheckFramebufferStatus
+#define glCheckFramebufferStatusOES wrap_glCheckFramebufferStatusOES
+#define glClear wrap_glClear
+#define glClearBufferfi wrap_glClearBufferfi
+#define glClearBufferfv wrap_glClearBufferfv
+#define glClearBufferiv wrap_glClearBufferiv
+#define glClearBufferuiv wrap_glClearBufferuiv
+#define glClearColor wrap_glClearColor
+#define glClearColorx wrap_glClearColorx
+#define glClearColorxOES wrap_glClearColorxOES
+#define glClearDepthf wrap_glClearDepthf
+#define glClearDepthfOES wrap_glClearDepthfOES
+#define glClearDepthx wrap_glClearDepthx
+#define glClearDepthxOES wrap_glClearDepthxOES
+#define glClearStencil wrap_glClearStencil
+#define glClientActiveTexture wrap_glClientActiveTexture
+#define glClientWaitSync wrap_glClientWaitSync
+#define glClientWaitSyncAPPLE wrap_glClientWaitSyncAPPLE
+#define glClipPlanef wrap_glClipPlanef
+#define glClipPlanefIMG wrap_glClipPlanefIMG
+#define glClipPlanefOES wrap_glClipPlanefOES
+#define glClipPlanex wrap_glClipPlanex
+#define glClipPlanexIMG wrap_glClipPlanexIMG
+#define glClipPlanexOES wrap_glClipPlanexOES
+#define glColor4f wrap_glColor4f
+#define glColor4ub wrap_glColor4ub
+#define glColor4x wrap_glColor4x
+#define glColor4xOES wrap_glColor4xOES
+#define glColorMask wrap_glColorMask
+#define glColorMaski wrap_glColorMaski
+#define glColorMaskiEXT wrap_glColorMaskiEXT
+#define glColorMaskiOES wrap_glColorMaskiOES
+#define glColorPointer wrap_glColorPointer
+#define glCompileShader wrap_glCompileShader
+#define glCompressedTexImage2D wrap_glCompressedTexImage2D
+#define glCompressedTexImage3D wrap_glCompressedTexImage3D
+#define glCompressedTexImage3DOES wrap_glCompressedTexImage3DOES
+#define glCompressedTexSubImage2D wrap_glCompressedTexSubImage2D
+#define glCompressedTexSubImage3D wrap_glCompressedTexSubImage3D
+#define glCompressedTexSubImage3DOES wrap_glCompressedTexSubImage3DOES
+#define glCopyBufferSubData wrap_glCopyBufferSubData
+#define glCopyBufferSubDataNV wrap_glCopyBufferSubDataNV
+#define glCopyImageSubData wrap_glCopyImageSubData
+#define glCopyImageSubDataEXT wrap_glCopyImageSubDataEXT
+#define glCopyImageSubDataOES wrap_glCopyImageSubDataOES
+#define glCopyPathNV wrap_glCopyPathNV
+#define glCopyTexImage2D wrap_glCopyTexImage2D
+#define glCopyTexSubImage2D wrap_glCopyTexSubImage2D
+#define glCopyTexSubImage3D wrap_glCopyTexSubImage3D
+#define glCopyTexSubImage3DOES wrap_glCopyTexSubImage3DOES
+#define glCopyTextureLevelsAPPLE wrap_glCopyTextureLevelsAPPLE
+#define glCoverFillPathInstancedNV wrap_glCoverFillPathInstancedNV
+#define glCoverFillPathNV wrap_glCoverFillPathNV
+#define glCoverStrokePathInstancedNV wrap_glCoverStrokePathInstancedNV
+#define glCoverStrokePathNV wrap_glCoverStrokePathNV
+#define glCoverageMaskNV wrap_glCoverageMaskNV
+#define glCoverageModulationNV wrap_glCoverageModulationNV
+#define glCoverageModulationTableNV wrap_glCoverageModulationTableNV
+#define glCoverageOperationNV wrap_glCoverageOperationNV
+#define glCreatePerfQueryINTEL wrap_glCreatePerfQueryINTEL
+#define glCreateProgram wrap_glCreateProgram
+#define glCreateShader wrap_glCreateShader
+#define glCreateShaderProgramv wrap_glCreateShaderProgramv
+#define glCreateShaderProgramvEXT wrap_glCreateShaderProgramvEXT
+#define glCullFace wrap_glCullFace
+#define glCurrentPaletteMatrixOES wrap_glCurrentPaletteMatrixOES
+#define glDebugMessageCallback wrap_glDebugMessageCallback
+#define glDebugMessageCallbackKHR wrap_glDebugMessageCallbackKHR
+#define glDebugMessageControl wrap_glDebugMessageControl
+#define glDebugMessageControlKHR wrap_glDebugMessageControlKHR
+#define glDebugMessageInsert wrap_glDebugMessageInsert
+#define glDebugMessageInsertKHR wrap_glDebugMessageInsertKHR
+#define glDeleteBuffers wrap_glDeleteBuffers
+#define glDeleteFencesNV wrap_glDeleteFencesNV
+#define glDeleteFramebuffers wrap_glDeleteFramebuffers
+#define glDeleteFramebuffersOES wrap_glDeleteFramebuffersOES
+#define glDeletePathsNV wrap_glDeletePathsNV
+#define glDeletePerfMonitorsAMD wrap_glDeletePerfMonitorsAMD
+#define glDeletePerfQueryINTEL wrap_glDeletePerfQueryINTEL
+#define glDeleteProgram wrap_glDeleteProgram
+#define glDeleteProgramPipelines wrap_glDeleteProgramPipelines
+#define glDeleteProgramPipelinesEXT wrap_glDeleteProgramPipelinesEXT
+#define glDeleteQueries wrap_glDeleteQueries
+#define glDeleteQueriesEXT wrap_glDeleteQueriesEXT
+#define glDeleteRenderbuffers wrap_glDeleteRenderbuffers
+#define glDeleteRenderbuffersOES wrap_glDeleteRenderbuffersOES
+#define glDeleteSamplers wrap_glDeleteSamplers
+#define glDeleteShader wrap_glDeleteShader
+#define glDeleteSync wrap_glDeleteSync
+#define glDeleteSyncAPPLE wrap_glDeleteSyncAPPLE
+#define glDeleteTextures wrap_glDeleteTextures
+#define glDeleteTransformFeedbacks wrap_glDeleteTransformFeedbacks
+#define glDeleteVertexArrays wrap_glDeleteVertexArrays
+#define glDeleteVertexArraysOES wrap_glDeleteVertexArraysOES
+#define glDepthFunc wrap_glDepthFunc
+#define glDepthMask wrap_glDepthMask
+#define glDepthRangeArrayfvNV wrap_glDepthRangeArrayfvNV
+#define glDepthRangeIndexedfNV wrap_glDepthRangeIndexedfNV
+#define glDepthRangef wrap_glDepthRangef
+#define glDepthRangefOES wrap_glDepthRangefOES
+#define glDepthRangex wrap_glDepthRangex
+#define glDepthRangexOES wrap_glDepthRangexOES
+#define glDetachShader wrap_glDetachShader
+#define glDisable wrap_glDisable
+#define glDisableClientState wrap_glDisableClientState
+#define glDisableDriverControlQCOM wrap_glDisableDriverControlQCOM
+#define glDisableVertexAttribArray wrap_glDisableVertexAttribArray
+#define glDisablei wrap_glDisablei
+#define glDisableiEXT wrap_glDisableiEXT
+#define glDisableiNV wrap_glDisableiNV
+#define glDisableiOES wrap_glDisableiOES
+#define glDiscardFramebufferEXT wrap_glDiscardFramebufferEXT
+#define glDispatchCompute wrap_glDispatchCompute
+#define glDispatchComputeIndirect wrap_glDispatchComputeIndirect
+#define glDrawArrays wrap_glDrawArrays
+#define glDrawArraysIndirect wrap_glDrawArraysIndirect
+#define glDrawArraysInstanced wrap_glDrawArraysInstanced
+#define glDrawArraysInstancedANGLE wrap_glDrawArraysInstancedANGLE
+#define glDrawArraysInstancedBaseInstanceEXT wrap_glDrawArraysInstancedBaseInstanceEXT
+#define glDrawArraysInstancedEXT wrap_glDrawArraysInstancedEXT
+#define glDrawArraysInstancedNV wrap_glDrawArraysInstancedNV
+#define glDrawBuffers wrap_glDrawBuffers
+#define glDrawBuffersEXT wrap_glDrawBuffersEXT
+#define glDrawBuffersIndexedEXT wrap_glDrawBuffersIndexedEXT
+#define glDrawBuffersNV wrap_glDrawBuffersNV
+#define glDrawElements wrap_glDrawElements
+#define glDrawElementsBaseVertex wrap_glDrawElementsBaseVertex
+#define glDrawElementsBaseVertexEXT wrap_glDrawElementsBaseVertexEXT
+#define glDrawElementsBaseVertexOES wrap_glDrawElementsBaseVertexOES
+#define glDrawElementsIndirect wrap_glDrawElementsIndirect
+#define glDrawElementsInstanced wrap_glDrawElementsInstanced
+#define glDrawElementsInstancedANGLE wrap_glDrawElementsInstancedANGLE
+#define glDrawElementsInstancedBaseInstanceEXT wrap_glDrawElementsInstancedBaseInstanceEXT
+#define glDrawElementsInstancedBaseVertex wrap_glDrawElementsInstancedBaseVertex
+#define glDrawElementsInstancedBaseVertexBaseInstanceEXT wrap_glDrawElementsInstancedBaseVertexBaseInstanceEXT
+#define glDrawElementsInstancedBaseVertexEXT wrap_glDrawElementsInstancedBaseVertexEXT
+#define glDrawElementsInstancedBaseVertexOES wrap_glDrawElementsInstancedBaseVertexOES
+#define glDrawElementsInstancedEXT wrap_glDrawElementsInstancedEXT
+#define glDrawElementsInstancedNV wrap_glDrawElementsInstancedNV
+#define glDrawRangeElements wrap_glDrawRangeElements
+#define glDrawRangeElementsBaseVertex wrap_glDrawRangeElementsBaseVertex
+#define glDrawRangeElementsBaseVertexEXT wrap_glDrawRangeElementsBaseVertexEXT
+#define glDrawRangeElementsBaseVertexOES wrap_glDrawRangeElementsBaseVertexOES
+#define glDrawTexfOES wrap_glDrawTexfOES
+#define glDrawTexfvOES wrap_glDrawTexfvOES
+#define glDrawTexiOES wrap_glDrawTexiOES
+#define glDrawTexivOES wrap_glDrawTexivOES
+#define glDrawTexsOES wrap_glDrawTexsOES
+#define glDrawTexsvOES wrap_glDrawTexsvOES
+#define glDrawTexxOES wrap_glDrawTexxOES
+#define glDrawTexxvOES wrap_glDrawTexxvOES
+#define glEGLImageTargetRenderbufferStorageOES wrap_glEGLImageTargetRenderbufferStorageOES
+#define glEGLImageTargetTexture2DOES wrap_glEGLImageTargetTexture2DOES
+#define glEnable wrap_glEnable
+#define glEnableClientState wrap_glEnableClientState
+#define glEnableDriverControlQCOM wrap_glEnableDriverControlQCOM
+#define glEnableVertexAttribArray wrap_glEnableVertexAttribArray
+#define glEnablei wrap_glEnablei
+#define glEnableiEXT wrap_glEnableiEXT
+#define glEnableiNV wrap_glEnableiNV
+#define glEnableiOES wrap_glEnableiOES
+#define glEndConditionalRenderNV wrap_glEndConditionalRenderNV
+#define glEndPerfMonitorAMD wrap_glEndPerfMonitorAMD
+#define glEndPerfQueryINTEL wrap_glEndPerfQueryINTEL
+#define glEndQuery wrap_glEndQuery
+#define glEndQueryEXT wrap_glEndQueryEXT
+#define glEndTilingQCOM wrap_glEndTilingQCOM
+#define glEndTransformFeedback wrap_glEndTransformFeedback
+#define glExtGetBufferPointervQCOM wrap_glExtGetBufferPointervQCOM
+#define glExtGetBuffersQCOM wrap_glExtGetBuffersQCOM
+#define glExtGetFramebuffersQCOM wrap_glExtGetFramebuffersQCOM
+#define glExtGetProgramBinarySourceQCOM wrap_glExtGetProgramBinarySourceQCOM
+#define glExtGetProgramsQCOM wrap_glExtGetProgramsQCOM
+#define glExtGetRenderbuffersQCOM wrap_glExtGetRenderbuffersQCOM
+#define glExtGetShadersQCOM wrap_glExtGetShadersQCOM
+#define glExtGetTexLevelParameterivQCOM wrap_glExtGetTexLevelParameterivQCOM
+#define glExtGetTexSubImageQCOM wrap_glExtGetTexSubImageQCOM
+#define glExtGetTexturesQCOM wrap_glExtGetTexturesQCOM
+#define glExtIsProgramBinaryQCOM wrap_glExtIsProgramBinaryQCOM
+#define glExtTexObjectStateOverrideiQCOM wrap_glExtTexObjectStateOverrideiQCOM
+#define glFenceSync wrap_glFenceSync
+#define glFenceSyncAPPLE wrap_glFenceSyncAPPLE
+#define glFinish wrap_glFinish
+#define glFinishFenceNV wrap_glFinishFenceNV
+#define glFlush wrap_glFlush
+#define glFlushMappedBufferRange wrap_glFlushMappedBufferRange
+#define glFlushMappedBufferRangeEXT wrap_glFlushMappedBufferRangeEXT
+#define glFogf wrap_glFogf
+#define glFogfv wrap_glFogfv
+#define glFogx wrap_glFogx
+#define glFogxOES wrap_glFogxOES
+#define glFogxv wrap_glFogxv
+#define glFogxvOES wrap_glFogxvOES
+#define glFragmentCoverageColorNV wrap_glFragmentCoverageColorNV
+#define glFramebufferParameteri wrap_glFramebufferParameteri
+#define glFramebufferRenderbuffer wrap_glFramebufferRenderbuffer
+#define glFramebufferRenderbufferOES wrap_glFramebufferRenderbufferOES
+#define glFramebufferSampleLocationsfvNV wrap_glFramebufferSampleLocationsfvNV
+#define glFramebufferTexture wrap_glFramebufferTexture
+#define glFramebufferTexture2D wrap_glFramebufferTexture2D
+#define glFramebufferTexture2DMultisampleEXT wrap_glFramebufferTexture2DMultisampleEXT
+#define glFramebufferTexture2DMultisampleIMG wrap_glFramebufferTexture2DMultisampleIMG
+#define glFramebufferTexture2DOES wrap_glFramebufferTexture2DOES
+#define glFramebufferTexture3DOES wrap_glFramebufferTexture3DOES
+#define glFramebufferTextureEXT wrap_glFramebufferTextureEXT
+#define glFramebufferTextureLayer wrap_glFramebufferTextureLayer
+#define glFramebufferTextureMultisampleMultiviewOVR wrap_glFramebufferTextureMultisampleMultiviewOVR
+#define glFramebufferTextureMultiviewOVR wrap_glFramebufferTextureMultiviewOVR
+#define glFramebufferTextureOES wrap_glFramebufferTextureOES
+#define glFrontFace wrap_glFrontFace
+#define glFrustumf wrap_glFrustumf
+#define glFrustumfOES wrap_glFrustumfOES
+#define glFrustumx wrap_glFrustumx
+#define glFrustumxOES wrap_glFrustumxOES
+#define glGenBuffers wrap_glGenBuffers
+#define glGenFencesNV wrap_glGenFencesNV
+#define glGenFramebuffers wrap_glGenFramebuffers
+#define glGenFramebuffersOES wrap_glGenFramebuffersOES
+#define glGenPathsNV wrap_glGenPathsNV
+#define glGenPerfMonitorsAMD wrap_glGenPerfMonitorsAMD
+#define glGenProgramPipelines wrap_glGenProgramPipelines
+#define glGenProgramPipelinesEXT wrap_glGenProgramPipelinesEXT
+#define glGenQueries wrap_glGenQueries
+#define glGenQueriesEXT wrap_glGenQueriesEXT
+#define glGenRenderbuffers wrap_glGenRenderbuffers
+#define glGenRenderbuffersOES wrap_glGenRenderbuffersOES
+#define glGenSamplers wrap_glGenSamplers
+#define glGenTextures wrap_glGenTextures
+#define glGenTransformFeedbacks wrap_glGenTransformFeedbacks
+#define glGenVertexArrays wrap_glGenVertexArrays
+#define glGenVertexArraysOES wrap_glGenVertexArraysOES
+#define glGenerateMipmap wrap_glGenerateMipmap
+#define glGenerateMipmapOES wrap_glGenerateMipmapOES
+#define glGetActiveAttrib wrap_glGetActiveAttrib
+#define glGetActiveUniform wrap_glGetActiveUniform
+#define glGetActiveUniformBlockName wrap_glGetActiveUniformBlockName
+#define glGetActiveUniformBlockiv wrap_glGetActiveUniformBlockiv
+#define glGetActiveUniformsiv wrap_glGetActiveUniformsiv
+#define glGetAttachedShaders wrap_glGetAttachedShaders
+#define glGetAttribLocation wrap_glGetAttribLocation
+#define glGetBooleani_v wrap_glGetBooleani_v
+#define glGetBooleanv wrap_glGetBooleanv
+#define glGetBufferParameteri64v wrap_glGetBufferParameteri64v
+#define glGetBufferParameteriv wrap_glGetBufferParameteriv
+#define glGetBufferPointerv wrap_glGetBufferPointerv
+#define glGetBufferPointervOES wrap_glGetBufferPointervOES
+#define glGetClipPlanef wrap_glGetClipPlanef
+#define glGetClipPlanefOES wrap_glGetClipPlanefOES
+#define glGetClipPlanex wrap_glGetClipPlanex
+#define glGetClipPlanexOES wrap_glGetClipPlanexOES
+#define glGetCoverageModulationTableNV wrap_glGetCoverageModulationTableNV
+#define glGetDebugMessageLog wrap_glGetDebugMessageLog
+#define glGetDebugMessageLogKHR wrap_glGetDebugMessageLogKHR
+#define glGetDriverControlStringQCOM wrap_glGetDriverControlStringQCOM
+#define glGetDriverControlsQCOM wrap_glGetDriverControlsQCOM
+#define glGetError wrap_glGetError
+#define glGetFenceivNV wrap_glGetFenceivNV
+#define glGetFirstPerfQueryIdINTEL wrap_glGetFirstPerfQueryIdINTEL
+#define glGetFixedv wrap_glGetFixedv
+#define glGetFixedvOES wrap_glGetFixedvOES
+#define glGetFloati_vNV wrap_glGetFloati_vNV
+#define glGetFloatv wrap_glGetFloatv
+#define glGetFragDataIndexEXT wrap_glGetFragDataIndexEXT
+#define glGetFragDataLocation wrap_glGetFragDataLocation
+#define glGetFramebufferAttachmentParameteriv wrap_glGetFramebufferAttachmentParameteriv
+#define glGetFramebufferAttachmentParameterivOES wrap_glGetFramebufferAttachmentParameterivOES
+#define glGetFramebufferParameteriv wrap_glGetFramebufferParameteriv
+#define glGetGraphicsResetStatus wrap_glGetGraphicsResetStatus
+#define glGetGraphicsResetStatusEXT wrap_glGetGraphicsResetStatusEXT
+#define glGetGraphicsResetStatusKHR wrap_glGetGraphicsResetStatusKHR
+#define glGetImageHandleNV wrap_glGetImageHandleNV
+#define glGetInteger64i_v wrap_glGetInteger64i_v
+#define glGetInteger64v wrap_glGetInteger64v
+#define glGetInteger64vAPPLE wrap_glGetInteger64vAPPLE
+#define glGetIntegeri_v wrap_glGetIntegeri_v
+#define glGetIntegeri_vEXT wrap_glGetIntegeri_vEXT
+#define glGetIntegerv wrap_glGetIntegerv
+#define glGetInternalformatSampleivNV wrap_glGetInternalformatSampleivNV
+#define glGetInternalformativ wrap_glGetInternalformativ
+#define glGetLightfv wrap_glGetLightfv
+#define glGetLightxv wrap_glGetLightxv
+#define glGetLightxvOES wrap_glGetLightxvOES
+#define glGetMaterialfv wrap_glGetMaterialfv
+#define glGetMaterialxv wrap_glGetMaterialxv
+#define glGetMaterialxvOES wrap_glGetMaterialxvOES
+#define glGetMultisamplefv wrap_glGetMultisamplefv
+#define glGetNextPerfQueryIdINTEL wrap_glGetNextPerfQueryIdINTEL
+#define glGetObjectLabel wrap_glGetObjectLabel
+#define glGetObjectLabelEXT wrap_glGetObjectLabelEXT
+#define glGetObjectLabelKHR wrap_glGetObjectLabelKHR
+#define glGetObjectPtrLabel wrap_glGetObjectPtrLabel
+#define glGetObjectPtrLabelKHR wrap_glGetObjectPtrLabelKHR
+#define glGetPathCommandsNV wrap_glGetPathCommandsNV
+#define glGetPathCoordsNV wrap_glGetPathCoordsNV
+#define glGetPathDashArrayNV wrap_glGetPathDashArrayNV
+#define glGetPathLengthNV wrap_glGetPathLengthNV
+#define glGetPathMetricRangeNV wrap_glGetPathMetricRangeNV
+#define glGetPathMetricsNV wrap_glGetPathMetricsNV
+#define glGetPathParameterfvNV wrap_glGetPathParameterfvNV
+#define glGetPathParameterivNV wrap_glGetPathParameterivNV
+#define glGetPathSpacingNV wrap_glGetPathSpacingNV
+#define glGetPerfCounterInfoINTEL wrap_glGetPerfCounterInfoINTEL
+#define glGetPerfMonitorCounterDataAMD wrap_glGetPerfMonitorCounterDataAMD
+#define glGetPerfMonitorCounterInfoAMD wrap_glGetPerfMonitorCounterInfoAMD
+#define glGetPerfMonitorCounterStringAMD wrap_glGetPerfMonitorCounterStringAMD
+#define glGetPerfMonitorCountersAMD wrap_glGetPerfMonitorCountersAMD
+#define glGetPerfMonitorGroupStringAMD wrap_glGetPerfMonitorGroupStringAMD
+#define glGetPerfMonitorGroupsAMD wrap_glGetPerfMonitorGroupsAMD
+#define glGetPerfQueryDataINTEL wrap_glGetPerfQueryDataINTEL
+#define glGetPerfQueryIdByNameINTEL wrap_glGetPerfQueryIdByNameINTEL
+#define glGetPerfQueryInfoINTEL wrap_glGetPerfQueryInfoINTEL
+#define glGetPointerv wrap_glGetPointerv
+#define glGetPointervKHR wrap_glGetPointervKHR
+#define glGetProgramBinary wrap_glGetProgramBinary
+#define glGetProgramBinaryOES wrap_glGetProgramBinaryOES
+#define glGetProgramInfoLog wrap_glGetProgramInfoLog
+#define glGetProgramInterfaceiv wrap_glGetProgramInterfaceiv
+#define glGetProgramPipelineInfoLog wrap_glGetProgramPipelineInfoLog
+#define glGetProgramPipelineInfoLogEXT wrap_glGetProgramPipelineInfoLogEXT
+#define glGetProgramPipelineiv wrap_glGetProgramPipelineiv
+#define glGetProgramPipelineivEXT wrap_glGetProgramPipelineivEXT
+#define glGetProgramResourceIndex wrap_glGetProgramResourceIndex
+#define glGetProgramResourceLocation wrap_glGetProgramResourceLocation
+#define glGetProgramResourceLocationIndexEXT wrap_glGetProgramResourceLocationIndexEXT
+#define glGetProgramResourceName wrap_glGetProgramResourceName
+#define glGetProgramResourcefvNV wrap_glGetProgramResourcefvNV
+#define glGetProgramResourceiv wrap_glGetProgramResourceiv
+#define glGetProgramiv wrap_glGetProgramiv
+#define glGetQueryObjecti64vEXT wrap_glGetQueryObjecti64vEXT
+#define glGetQueryObjectivEXT wrap_glGetQueryObjectivEXT
+#define glGetQueryObjectui64vEXT wrap_glGetQueryObjectui64vEXT
+#define glGetQueryObjectuiv wrap_glGetQueryObjectuiv
+#define glGetQueryObjectuivEXT wrap_glGetQueryObjectuivEXT
+#define glGetQueryiv wrap_glGetQueryiv
+#define glGetQueryivEXT wrap_glGetQueryivEXT
+#define glGetRenderbufferParameteriv wrap_glGetRenderbufferParameteriv
+#define glGetRenderbufferParameterivOES wrap_glGetRenderbufferParameterivOES
+#define glGetSamplerParameterIiv wrap_glGetSamplerParameterIiv
+#define glGetSamplerParameterIivEXT wrap_glGetSamplerParameterIivEXT
+#define glGetSamplerParameterIivOES wrap_glGetSamplerParameterIivOES
+#define glGetSamplerParameterIuiv wrap_glGetSamplerParameterIuiv
+#define glGetSamplerParameterIuivEXT wrap_glGetSamplerParameterIuivEXT
+#define glGetSamplerParameterIuivOES wrap_glGetSamplerParameterIuivOES
+#define glGetSamplerParameterfv wrap_glGetSamplerParameterfv
+#define glGetSamplerParameteriv wrap_glGetSamplerParameteriv
+#define glGetShaderInfoLog wrap_glGetShaderInfoLog
+#define glGetShaderPrecisionFormat wrap_glGetShaderPrecisionFormat
+#define glGetShaderSource wrap_glGetShaderSource
+#define glGetShaderiv wrap_glGetShaderiv
+#define glGetString wrap_glGetString
+#define glGetStringi wrap_glGetStringi
+#define glGetSynciv wrap_glGetSynciv
+#define glGetSyncivAPPLE wrap_glGetSyncivAPPLE
+#define glGetTexEnvfv wrap_glGetTexEnvfv
+#define glGetTexEnviv wrap_glGetTexEnviv
+#define glGetTexEnvxv wrap_glGetTexEnvxv
+#define glGetTexEnvxvOES wrap_glGetTexEnvxvOES
+#define glGetTexGenfvOES wrap_glGetTexGenfvOES
+#define glGetTexGenivOES wrap_glGetTexGenivOES
+#define glGetTexGenxvOES wrap_glGetTexGenxvOES
+#define glGetTexLevelParameterfv wrap_glGetTexLevelParameterfv
+#define glGetTexLevelParameteriv wrap_glGetTexLevelParameteriv
+#define glGetTexParameterIiv wrap_glGetTexParameterIiv
+#define glGetTexParameterIivEXT wrap_glGetTexParameterIivEXT
+#define glGetTexParameterIivOES wrap_glGetTexParameterIivOES
+#define glGetTexParameterIuiv wrap_glGetTexParameterIuiv
+#define glGetTexParameterIuivEXT wrap_glGetTexParameterIuivEXT
+#define glGetTexParameterIuivOES wrap_glGetTexParameterIuivOES
+#define glGetTexParameterfv wrap_glGetTexParameterfv
+#define glGetTexParameteriv wrap_glGetTexParameteriv
+#define glGetTexParameterxv wrap_glGetTexParameterxv
+#define glGetTexParameterxvOES wrap_glGetTexParameterxvOES
+#define glGetTextureHandleNV wrap_glGetTextureHandleNV
+#define glGetTextureSamplerHandleNV wrap_glGetTextureSamplerHandleNV
+#define glGetTransformFeedbackVarying wrap_glGetTransformFeedbackVarying
+#define glGetTranslatedShaderSourceANGLE wrap_glGetTranslatedShaderSourceANGLE
+#define glGetUniformBlockIndex wrap_glGetUniformBlockIndex
+#define glGetUniformIndices wrap_glGetUniformIndices
+#define glGetUniformLocation wrap_glGetUniformLocation
+#define glGetUniformfv wrap_glGetUniformfv
+#define glGetUniformiv wrap_glGetUniformiv
+#define glGetUniformuiv wrap_glGetUniformuiv
+#define glGetVertexAttribIiv wrap_glGetVertexAttribIiv
+#define glGetVertexAttribIuiv wrap_glGetVertexAttribIuiv
+#define glGetVertexAttribPointerv wrap_glGetVertexAttribPointerv
+#define glGetVertexAttribfv wrap_glGetVertexAttribfv
+#define glGetVertexAttribiv wrap_glGetVertexAttribiv
+#define glGetnUniformfv wrap_glGetnUniformfv
+#define glGetnUniformfvEXT wrap_glGetnUniformfvEXT
+#define glGetnUniformfvKHR wrap_glGetnUniformfvKHR
+#define glGetnUniformiv wrap_glGetnUniformiv
+#define glGetnUniformivEXT wrap_glGetnUniformivEXT
+#define glGetnUniformivKHR wrap_glGetnUniformivKHR
+#define glGetnUniformuiv wrap_glGetnUniformuiv
+#define glGetnUniformuivKHR wrap_glGetnUniformuivKHR
+#define glHint wrap_glHint
+#define glInsertEventMarkerEXT wrap_glInsertEventMarkerEXT
+#define glInterpolatePathsNV wrap_glInterpolatePathsNV
+#define glInvalidateFramebuffer wrap_glInvalidateFramebuffer
+#define glInvalidateSubFramebuffer wrap_glInvalidateSubFramebuffer
+#define glIsBuffer wrap_glIsBuffer
+#define glIsEnabled wrap_glIsEnabled
+#define glIsEnabledi wrap_glIsEnabledi
+#define glIsEnablediEXT wrap_glIsEnablediEXT
+#define glIsEnablediNV wrap_glIsEnablediNV
+#define glIsEnablediOES wrap_glIsEnablediOES
+#define glIsFenceNV wrap_glIsFenceNV
+#define glIsFramebuffer wrap_glIsFramebuffer
+#define glIsFramebufferOES wrap_glIsFramebufferOES
+#define glIsImageHandleResidentNV wrap_glIsImageHandleResidentNV
+#define glIsPathNV wrap_glIsPathNV
+#define glIsPointInFillPathNV wrap_glIsPointInFillPathNV
+#define glIsPointInStrokePathNV wrap_glIsPointInStrokePathNV
+#define glIsProgram wrap_glIsProgram
+#define glIsProgramPipeline wrap_glIsProgramPipeline
+#define glIsProgramPipelineEXT wrap_glIsProgramPipelineEXT
+#define glIsQuery wrap_glIsQuery
+#define glIsQueryEXT wrap_glIsQueryEXT
+#define glIsRenderbuffer wrap_glIsRenderbuffer
+#define glIsRenderbufferOES wrap_glIsRenderbufferOES
+#define glIsSampler wrap_glIsSampler
+#define glIsShader wrap_glIsShader
+#define glIsSync wrap_glIsSync
+#define glIsSyncAPPLE wrap_glIsSyncAPPLE
+#define glIsTexture wrap_glIsTexture
+#define glIsTextureHandleResidentNV wrap_glIsTextureHandleResidentNV
+#define glIsTransformFeedback wrap_glIsTransformFeedback
+#define glIsVertexArray wrap_glIsVertexArray
+#define glIsVertexArrayOES wrap_glIsVertexArrayOES
+#define glLabelObjectEXT wrap_glLabelObjectEXT
+#define glLightModelf wrap_glLightModelf
+#define glLightModelfv wrap_glLightModelfv
+#define glLightModelx wrap_glLightModelx
+#define glLightModelxOES wrap_glLightModelxOES
+#define glLightModelxv wrap_glLightModelxv
+#define glLightModelxvOES wrap_glLightModelxvOES
+#define glLightf wrap_glLightf
+#define glLightfv wrap_glLightfv
+#define glLightx wrap_glLightx
+#define glLightxOES wrap_glLightxOES
+#define glLightxv wrap_glLightxv
+#define glLightxvOES wrap_glLightxvOES
+#define glLineWidth wrap_glLineWidth
+#define glLineWidthx wrap_glLineWidthx
+#define glLineWidthxOES wrap_glLineWidthxOES
+#define glLinkProgram wrap_glLinkProgram
+#define glLoadIdentity wrap_glLoadIdentity
+#define glLoadMatrixf wrap_glLoadMatrixf
+#define glLoadMatrixx wrap_glLoadMatrixx
+#define glLoadMatrixxOES wrap_glLoadMatrixxOES
+#define glLoadPaletteFromModelViewMatrixOES wrap_glLoadPaletteFromModelViewMatrixOES
+#define glLogicOp wrap_glLogicOp
+#define glMakeImageHandleNonResidentNV wrap_glMakeImageHandleNonResidentNV
+#define glMakeImageHandleResidentNV wrap_glMakeImageHandleResidentNV
+#define glMakeTextureHandleNonResidentNV wrap_glMakeTextureHandleNonResidentNV
+#define glMakeTextureHandleResidentNV wrap_glMakeTextureHandleResidentNV
+#define glMapBufferOES wrap_glMapBufferOES
+#define glMapBufferRange wrap_glMapBufferRange
+#define glMapBufferRangeEXT wrap_glMapBufferRangeEXT
+#define glMaterialf wrap_glMaterialf
+#define glMaterialfv wrap_glMaterialfv
+#define glMaterialx wrap_glMaterialx
+#define glMaterialxOES wrap_glMaterialxOES
+#define glMaterialxv wrap_glMaterialxv
+#define glMaterialxvOES wrap_glMaterialxvOES
+#define glMatrixIndexPointerOES wrap_glMatrixIndexPointerOES
+#define glMatrixLoad3x2fNV wrap_glMatrixLoad3x2fNV
+#define glMatrixLoad3x3fNV wrap_glMatrixLoad3x3fNV
+#define glMatrixLoadTranspose3x3fNV wrap_glMatrixLoadTranspose3x3fNV
+#define glMatrixMode wrap_glMatrixMode
+#define glMatrixMult3x2fNV wrap_glMatrixMult3x2fNV
+#define glMatrixMult3x3fNV wrap_glMatrixMult3x3fNV
+#define glMatrixMultTranspose3x3fNV wrap_glMatrixMultTranspose3x3fNV
+#define glMemoryBarrier wrap_glMemoryBarrier
+#define glMemoryBarrierByRegion wrap_glMemoryBarrierByRegion
+#define glMinSampleShading wrap_glMinSampleShading
+#define glMinSampleShadingOES wrap_glMinSampleShadingOES
+#define glMultMatrixf wrap_glMultMatrixf
+#define glMultMatrixx wrap_glMultMatrixx
+#define glMultMatrixxOES wrap_glMultMatrixxOES
+#define glMultiDrawArraysEXT wrap_glMultiDrawArraysEXT
+#define glMultiDrawArraysIndirectEXT wrap_glMultiDrawArraysIndirectEXT
+#define glMultiDrawElementsBaseVertexEXT wrap_glMultiDrawElementsBaseVertexEXT
+#define glMultiDrawElementsBaseVertexOES wrap_glMultiDrawElementsBaseVertexOES
+#define glMultiDrawElementsEXT wrap_glMultiDrawElementsEXT
+#define glMultiDrawElementsIndirectEXT wrap_glMultiDrawElementsIndirectEXT
+#define glMultiTexCoord4f wrap_glMultiTexCoord4f
+#define glMultiTexCoord4x wrap_glMultiTexCoord4x
+#define glMultiTexCoord4xOES wrap_glMultiTexCoord4xOES
+#define glNamedFramebufferSampleLocationsfvNV wrap_glNamedFramebufferSampleLocationsfvNV
+#define glNormal3f wrap_glNormal3f
+#define glNormal3x wrap_glNormal3x
+#define glNormal3xOES wrap_glNormal3xOES
+#define glNormalPointer wrap_glNormalPointer
+#define glObjectLabel wrap_glObjectLabel
+#define glObjectLabelKHR wrap_glObjectLabelKHR
+#define glObjectPtrLabel wrap_glObjectPtrLabel
+#define glObjectPtrLabelKHR wrap_glObjectPtrLabelKHR
+#define glOrthof wrap_glOrthof
+#define glOrthofOES wrap_glOrthofOES
+#define glOrthox wrap_glOrthox
+#define glOrthoxOES wrap_glOrthoxOES
+#define glPatchParameteri wrap_glPatchParameteri
+#define glPatchParameteriEXT wrap_glPatchParameteriEXT
+#define glPatchParameteriOES wrap_glPatchParameteriOES
+#define glPathCommandsNV wrap_glPathCommandsNV
+#define glPathCoordsNV wrap_glPathCoordsNV
+#define glPathCoverDepthFuncNV wrap_glPathCoverDepthFuncNV
+#define glPathDashArrayNV wrap_glPathDashArrayNV
+#define glPathGlyphIndexArrayNV wrap_glPathGlyphIndexArrayNV
+#define glPathGlyphIndexRangeNV wrap_glPathGlyphIndexRangeNV
+#define glPathGlyphRangeNV wrap_glPathGlyphRangeNV
+#define glPathGlyphsNV wrap_glPathGlyphsNV
+#define glPathMemoryGlyphIndexArrayNV wrap_glPathMemoryGlyphIndexArrayNV
+#define glPathParameterfNV wrap_glPathParameterfNV
+#define glPathParameterfvNV wrap_glPathParameterfvNV
+#define glPathParameteriNV wrap_glPathParameteriNV
+#define glPathParameterivNV wrap_glPathParameterivNV
+#define glPathStencilDepthOffsetNV wrap_glPathStencilDepthOffsetNV
+#define glPathStencilFuncNV wrap_glPathStencilFuncNV
+#define glPathStringNV wrap_glPathStringNV
+#define glPathSubCommandsNV wrap_glPathSubCommandsNV
+#define glPathSubCoordsNV wrap_glPathSubCoordsNV
+#define glPauseTransformFeedback wrap_glPauseTransformFeedback
+#define glPixelStorei wrap_glPixelStorei
+#define glPointAlongPathNV wrap_glPointAlongPathNV
+#define glPointParameterf wrap_glPointParameterf
+#define glPointParameterfv wrap_glPointParameterfv
+#define glPointParameterx wrap_glPointParameterx
+#define glPointParameterxOES wrap_glPointParameterxOES
+#define glPointParameterxv wrap_glPointParameterxv
+#define glPointParameterxvOES wrap_glPointParameterxvOES
+#define glPointSize wrap_glPointSize
+#define glPointSizePointerOES wrap_glPointSizePointerOES
+#define glPointSizex wrap_glPointSizex
+#define glPointSizexOES wrap_glPointSizexOES
+#define glPolygonModeNV wrap_glPolygonModeNV
+#define glPolygonOffset wrap_glPolygonOffset
+#define glPolygonOffsetx wrap_glPolygonOffsetx
+#define glPolygonOffsetxOES wrap_glPolygonOffsetxOES
+#define glPopDebugGroup wrap_glPopDebugGroup
+#define glPopDebugGroupKHR wrap_glPopDebugGroupKHR
+#define glPopGroupMarkerEXT wrap_glPopGroupMarkerEXT
+#define glPopMatrix wrap_glPopMatrix
+#define glPrimitiveBoundingBox wrap_glPrimitiveBoundingBox
+#define glPrimitiveBoundingBoxEXT wrap_glPrimitiveBoundingBoxEXT
+#define glPrimitiveBoundingBoxOES wrap_glPrimitiveBoundingBoxOES
+#define glProgramBinary wrap_glProgramBinary
+#define glProgramBinaryOES wrap_glProgramBinaryOES
+#define glProgramParameteri wrap_glProgramParameteri
+#define glProgramParameteriEXT wrap_glProgramParameteriEXT
+#define glProgramPathFragmentInputGenNV wrap_glProgramPathFragmentInputGenNV
+#define glProgramUniform1f wrap_glProgramUniform1f
+#define glProgramUniform1fEXT wrap_glProgramUniform1fEXT
+#define glProgramUniform1fv wrap_glProgramUniform1fv
+#define glProgramUniform1fvEXT wrap_glProgramUniform1fvEXT
+#define glProgramUniform1i wrap_glProgramUniform1i
+#define glProgramUniform1iEXT wrap_glProgramUniform1iEXT
+#define glProgramUniform1iv wrap_glProgramUniform1iv
+#define glProgramUniform1ivEXT wrap_glProgramUniform1ivEXT
+#define glProgramUniform1ui wrap_glProgramUniform1ui
+#define glProgramUniform1uiEXT wrap_glProgramUniform1uiEXT
+#define glProgramUniform1uiv wrap_glProgramUniform1uiv
+#define glProgramUniform1uivEXT wrap_glProgramUniform1uivEXT
+#define glProgramUniform2f wrap_glProgramUniform2f
+#define glProgramUniform2fEXT wrap_glProgramUniform2fEXT
+#define glProgramUniform2fv wrap_glProgramUniform2fv
+#define glProgramUniform2fvEXT wrap_glProgramUniform2fvEXT
+#define glProgramUniform2i wrap_glProgramUniform2i
+#define glProgramUniform2iEXT wrap_glProgramUniform2iEXT
+#define glProgramUniform2iv wrap_glProgramUniform2iv
+#define glProgramUniform2ivEXT wrap_glProgramUniform2ivEXT
+#define glProgramUniform2ui wrap_glProgramUniform2ui
+#define glProgramUniform2uiEXT wrap_glProgramUniform2uiEXT
+#define glProgramUniform2uiv wrap_glProgramUniform2uiv
+#define glProgramUniform2uivEXT wrap_glProgramUniform2uivEXT
+#define glProgramUniform3f wrap_glProgramUniform3f
+#define glProgramUniform3fEXT wrap_glProgramUniform3fEXT
+#define glProgramUniform3fv wrap_glProgramUniform3fv
+#define glProgramUniform3fvEXT wrap_glProgramUniform3fvEXT
+#define glProgramUniform3i wrap_glProgramUniform3i
+#define glProgramUniform3iEXT wrap_glProgramUniform3iEXT
+#define glProgramUniform3iv wrap_glProgramUniform3iv
+#define glProgramUniform3ivEXT wrap_glProgramUniform3ivEXT
+#define glProgramUniform3ui wrap_glProgramUniform3ui
+#define glProgramUniform3uiEXT wrap_glProgramUniform3uiEXT
+#define glProgramUniform3uiv wrap_glProgramUniform3uiv
+#define glProgramUniform3uivEXT wrap_glProgramUniform3uivEXT
+#define glProgramUniform4f wrap_glProgramUniform4f
+#define glProgramUniform4fEXT wrap_glProgramUniform4fEXT
+#define glProgramUniform4fv wrap_glProgramUniform4fv
+#define glProgramUniform4fvEXT wrap_glProgramUniform4fvEXT
+#define glProgramUniform4i wrap_glProgramUniform4i
+#define glProgramUniform4iEXT wrap_glProgramUniform4iEXT
+#define glProgramUniform4iv wrap_glProgramUniform4iv
+#define glProgramUniform4ivEXT wrap_glProgramUniform4ivEXT
+#define glProgramUniform4ui wrap_glProgramUniform4ui
+#define glProgramUniform4uiEXT wrap_glProgramUniform4uiEXT
+#define glProgramUniform4uiv wrap_glProgramUniform4uiv
+#define glProgramUniform4uivEXT wrap_glProgramUniform4uivEXT
+#define glProgramUniformHandleui64NV wrap_glProgramUniformHandleui64NV
+#define glProgramUniformHandleui64vNV wrap_glProgramUniformHandleui64vNV
+#define glProgramUniformMatrix2fv wrap_glProgramUniformMatrix2fv
+#define glProgramUniformMatrix2fvEXT wrap_glProgramUniformMatrix2fvEXT
+#define glProgramUniformMatrix2x3fv wrap_glProgramUniformMatrix2x3fv
+#define glProgramUniformMatrix2x3fvEXT wrap_glProgramUniformMatrix2x3fvEXT
+#define glProgramUniformMatrix2x4fv wrap_glProgramUniformMatrix2x4fv
+#define glProgramUniformMatrix2x4fvEXT wrap_glProgramUniformMatrix2x4fvEXT
+#define glProgramUniformMatrix3fv wrap_glProgramUniformMatrix3fv
+#define glProgramUniformMatrix3fvEXT wrap_glProgramUniformMatrix3fvEXT
+#define glProgramUniformMatrix3x2fv wrap_glProgramUniformMatrix3x2fv
+#define glProgramUniformMatrix3x2fvEXT wrap_glProgramUniformMatrix3x2fvEXT
+#define glProgramUniformMatrix3x4fv wrap_glProgramUniformMatrix3x4fv
+#define glProgramUniformMatrix3x4fvEXT wrap_glProgramUniformMatrix3x4fvEXT
+#define glProgramUniformMatrix4fv wrap_glProgramUniformMatrix4fv
+#define glProgramUniformMatrix4fvEXT wrap_glProgramUniformMatrix4fvEXT
+#define glProgramUniformMatrix4x2fv wrap_glProgramUniformMatrix4x2fv
+#define glProgramUniformMatrix4x2fvEXT wrap_glProgramUniformMatrix4x2fvEXT
+#define glProgramUniformMatrix4x3fv wrap_glProgramUniformMatrix4x3fv
+#define glProgramUniformMatrix4x3fvEXT wrap_glProgramUniformMatrix4x3fvEXT
+#define glPushDebugGroup wrap_glPushDebugGroup
+#define glPushDebugGroupKHR wrap_glPushDebugGroupKHR
+#define glPushGroupMarkerEXT wrap_glPushGroupMarkerEXT
+#define glPushMatrix wrap_glPushMatrix
+#define glQueryCounterEXT wrap_glQueryCounterEXT
+#define glQueryMatrixxOES wrap_glQueryMatrixxOES
+#define glRasterSamplesEXT wrap_glRasterSamplesEXT
+#define glReadBuffer wrap_glReadBuffer
+#define glReadBufferIndexedEXT wrap_glReadBufferIndexedEXT
+#define glReadBufferNV wrap_glReadBufferNV
+#define glReadPixels wrap_glReadPixels
+#define glReadnPixels wrap_glReadnPixels
+#define glReadnPixelsEXT wrap_glReadnPixelsEXT
+#define glReadnPixelsKHR wrap_glReadnPixelsKHR
+#define glReleaseShaderCompiler wrap_glReleaseShaderCompiler
+#define glRenderbufferStorage wrap_glRenderbufferStorage
+#define glRenderbufferStorageMultisample wrap_glRenderbufferStorageMultisample
+#define glRenderbufferStorageMultisampleANGLE wrap_glRenderbufferStorageMultisampleANGLE
+#define glRenderbufferStorageMultisampleAPPLE wrap_glRenderbufferStorageMultisampleAPPLE
+#define glRenderbufferStorageMultisampleEXT wrap_glRenderbufferStorageMultisampleEXT
+#define glRenderbufferStorageMultisampleIMG wrap_glRenderbufferStorageMultisampleIMG
+#define glRenderbufferStorageMultisampleNV wrap_glRenderbufferStorageMultisampleNV
+#define glRenderbufferStorageOES wrap_glRenderbufferStorageOES
+#define glResolveDepthValuesNV wrap_glResolveDepthValuesNV
+#define glResolveMultisampleFramebufferAPPLE wrap_glResolveMultisampleFramebufferAPPLE
+#define glResumeTransformFeedback wrap_glResumeTransformFeedback
+#define glRotatef wrap_glRotatef
+#define glRotatex wrap_glRotatex
+#define glRotatexOES wrap_glRotatexOES
+#define glSampleCoverage wrap_glSampleCoverage
+#define glSampleCoveragex wrap_glSampleCoveragex
+#define glSampleCoveragexOES wrap_glSampleCoveragexOES
+#define glSampleMaski wrap_glSampleMaski
+#define glSamplerParameterIiv wrap_glSamplerParameterIiv
+#define glSamplerParameterIivEXT wrap_glSamplerParameterIivEXT
+#define glSamplerParameterIivOES wrap_glSamplerParameterIivOES
+#define glSamplerParameterIuiv wrap_glSamplerParameterIuiv
+#define glSamplerParameterIuivEXT wrap_glSamplerParameterIuivEXT
+#define glSamplerParameterIuivOES wrap_glSamplerParameterIuivOES
+#define glSamplerParameterf wrap_glSamplerParameterf
+#define glSamplerParameterfv wrap_glSamplerParameterfv
+#define glSamplerParameteri wrap_glSamplerParameteri
+#define glSamplerParameteriv wrap_glSamplerParameteriv
+#define glScalef wrap_glScalef
+#define glScalex wrap_glScalex
+#define glScalexOES wrap_glScalexOES
+#define glScissor wrap_glScissor
+#define glScissorArrayvNV wrap_glScissorArrayvNV
+#define glScissorIndexedNV wrap_glScissorIndexedNV
+#define glScissorIndexedvNV wrap_glScissorIndexedvNV
+#define glSelectPerfMonitorCountersAMD wrap_glSelectPerfMonitorCountersAMD
+#define glSetFenceNV wrap_glSetFenceNV
+#define glShadeModel wrap_glShadeModel
+#define glShaderBinary wrap_glShaderBinary
+#define glShaderSource wrap_glShaderSource
+#define glStartTilingQCOM wrap_glStartTilingQCOM
+#define glStencilFillPathInstancedNV wrap_glStencilFillPathInstancedNV
+#define glStencilFillPathNV wrap_glStencilFillPathNV
+#define glStencilFunc wrap_glStencilFunc
+#define glStencilFuncSeparate wrap_glStencilFuncSeparate
+#define glStencilMask wrap_glStencilMask
+#define glStencilMaskSeparate wrap_glStencilMaskSeparate
+#define glStencilOp wrap_glStencilOp
+#define glStencilOpSeparate wrap_glStencilOpSeparate
+#define glStencilStrokePathInstancedNV wrap_glStencilStrokePathInstancedNV
+#define glStencilStrokePathNV wrap_glStencilStrokePathNV
+#define glStencilThenCoverFillPathInstancedNV wrap_glStencilThenCoverFillPathInstancedNV
+#define glStencilThenCoverFillPathNV wrap_glStencilThenCoverFillPathNV
+#define glStencilThenCoverStrokePathInstancedNV wrap_glStencilThenCoverStrokePathInstancedNV
+#define glStencilThenCoverStrokePathNV wrap_glStencilThenCoverStrokePathNV
+#define glSubpixelPrecisionBiasNV wrap_glSubpixelPrecisionBiasNV
+#define glTestFenceNV wrap_glTestFenceNV
+#define glTexBuffer wrap_glTexBuffer
+#define glTexBufferEXT wrap_glTexBufferEXT
+#define glTexBufferOES wrap_glTexBufferOES
+#define glTexBufferRange wrap_glTexBufferRange
+#define glTexBufferRangeEXT wrap_glTexBufferRangeEXT
+#define glTexBufferRangeOES wrap_glTexBufferRangeOES
+#define glTexCoordPointer wrap_glTexCoordPointer
+#define glTexEnvf wrap_glTexEnvf
+#define glTexEnvfv wrap_glTexEnvfv
+#define glTexEnvi wrap_glTexEnvi
+#define glTexEnviv wrap_glTexEnviv
+#define glTexEnvx wrap_glTexEnvx
+#define glTexEnvxOES wrap_glTexEnvxOES
+#define glTexEnvxv wrap_glTexEnvxv
+#define glTexEnvxvOES wrap_glTexEnvxvOES
+#define glTexGenfOES wrap_glTexGenfOES
+#define glTexGenfvOES wrap_glTexGenfvOES
+#define glTexGeniOES wrap_glTexGeniOES
+#define glTexGenivOES wrap_glTexGenivOES
+#define glTexGenxOES wrap_glTexGenxOES
+#define glTexGenxvOES wrap_glTexGenxvOES
+#define glTexImage2D wrap_glTexImage2D
+#define glTexImage3D wrap_glTexImage3D
+#define glTexImage3DOES wrap_glTexImage3DOES
+#define glTexPageCommitmentEXT wrap_glTexPageCommitmentEXT
+#define glTexParameterIiv wrap_glTexParameterIiv
+#define glTexParameterIivEXT wrap_glTexParameterIivEXT
+#define glTexParameterIivOES wrap_glTexParameterIivOES
+#define glTexParameterIuiv wrap_glTexParameterIuiv
+#define glTexParameterIuivEXT wrap_glTexParameterIuivEXT
+#define glTexParameterIuivOES wrap_glTexParameterIuivOES
+#define glTexParameterf wrap_glTexParameterf
+#define glTexParameterfv wrap_glTexParameterfv
+#define glTexParameteri wrap_glTexParameteri
+#define glTexParameteriv wrap_glTexParameteriv
+#define glTexParameterx wrap_glTexParameterx
+#define glTexParameterxOES wrap_glTexParameterxOES
+#define glTexParameterxv wrap_glTexParameterxv
+#define glTexParameterxvOES wrap_glTexParameterxvOES
+#define glTexStorage1DEXT wrap_glTexStorage1DEXT
+#define glTexStorage2D wrap_glTexStorage2D
+#define glTexStorage2DEXT wrap_glTexStorage2DEXT
+#define glTexStorage2DMultisample wrap_glTexStorage2DMultisample
+#define glTexStorage3D wrap_glTexStorage3D
+#define glTexStorage3DEXT wrap_glTexStorage3DEXT
+#define glTexStorage3DMultisample wrap_glTexStorage3DMultisample
+#define glTexStorage3DMultisampleOES wrap_glTexStorage3DMultisampleOES
+#define glTexSubImage2D wrap_glTexSubImage2D
+#define glTexSubImage3D wrap_glTexSubImage3D
+#define glTexSubImage3DOES wrap_glTexSubImage3DOES
+#define glTextureStorage1DEXT wrap_glTextureStorage1DEXT
+#define glTextureStorage2DEXT wrap_glTextureStorage2DEXT
+#define glTextureStorage3DEXT wrap_glTextureStorage3DEXT
+#define glTextureViewEXT wrap_glTextureViewEXT
+#define glTextureViewOES wrap_glTextureViewOES
+#define glTransformFeedbackVaryings wrap_glTransformFeedbackVaryings
+#define glTransformPathNV wrap_glTransformPathNV
+#define glTranslatef wrap_glTranslatef
+#define glTranslatex wrap_glTranslatex
+#define glTranslatexOES wrap_glTranslatexOES
+#define glUniform1f wrap_glUniform1f
+#define glUniform1fv wrap_glUniform1fv
+#define glUniform1i wrap_glUniform1i
+#define glUniform1iv wrap_glUniform1iv
+#define glUniform1ui wrap_glUniform1ui
+#define glUniform1uiv wrap_glUniform1uiv
+#define glUniform2f wrap_glUniform2f
+#define glUniform2fv wrap_glUniform2fv
+#define glUniform2i wrap_glUniform2i
+#define glUniform2iv wrap_glUniform2iv
+#define glUniform2ui wrap_glUniform2ui
+#define glUniform2uiv wrap_glUniform2uiv
+#define glUniform3f wrap_glUniform3f
+#define glUniform3fv wrap_glUniform3fv
+#define glUniform3i wrap_glUniform3i
+#define glUniform3iv wrap_glUniform3iv
+#define glUniform3ui wrap_glUniform3ui
+#define glUniform3uiv wrap_glUniform3uiv
+#define glUniform4f wrap_glUniform4f
+#define glUniform4fv wrap_glUniform4fv
+#define glUniform4i wrap_glUniform4i
+#define glUniform4iv wrap_glUniform4iv
+#define glUniform4ui wrap_glUniform4ui
+#define glUniform4uiv wrap_glUniform4uiv
+#define glUniformBlockBinding wrap_glUniformBlockBinding
+#define glUniformHandleui64NV wrap_glUniformHandleui64NV
+#define glUniformHandleui64vNV wrap_glUniformHandleui64vNV
+#define glUniformMatrix2fv wrap_glUniformMatrix2fv
+#define glUniformMatrix2x3fv wrap_glUniformMatrix2x3fv
+#define glUniformMatrix2x3fvNV wrap_glUniformMatrix2x3fvNV
+#define glUniformMatrix2x4fv wrap_glUniformMatrix2x4fv
+#define glUniformMatrix2x4fvNV wrap_glUniformMatrix2x4fvNV
+#define glUniformMatrix3fv wrap_glUniformMatrix3fv
+#define glUniformMatrix3x2fv wrap_glUniformMatrix3x2fv
+#define glUniformMatrix3x2fvNV wrap_glUniformMatrix3x2fvNV
+#define glUniformMatrix3x4fv wrap_glUniformMatrix3x4fv
+#define glUniformMatrix3x4fvNV wrap_glUniformMatrix3x4fvNV
+#define glUniformMatrix4fv wrap_glUniformMatrix4fv
+#define glUniformMatrix4x2fv wrap_glUniformMatrix4x2fv
+#define glUniformMatrix4x2fvNV wrap_glUniformMatrix4x2fvNV
+#define glUniformMatrix4x3fv wrap_glUniformMatrix4x3fv
+#define glUniformMatrix4x3fvNV wrap_glUniformMatrix4x3fvNV
+#define glUnmapBuffer wrap_glUnmapBuffer
+#define glUnmapBufferOES wrap_glUnmapBufferOES
+#define glUseProgram wrap_glUseProgram
+#define glUseProgramStages wrap_glUseProgramStages
+#define glUseProgramStagesEXT wrap_glUseProgramStagesEXT
+#define glValidateProgram wrap_glValidateProgram
+#define glValidateProgramPipeline wrap_glValidateProgramPipeline
+#define glValidateProgramPipelineEXT wrap_glValidateProgramPipelineEXT
+#define glVertexAttrib1f wrap_glVertexAttrib1f
+#define glVertexAttrib1fv wrap_glVertexAttrib1fv
+#define glVertexAttrib2f wrap_glVertexAttrib2f
+#define glVertexAttrib2fv wrap_glVertexAttrib2fv
+#define glVertexAttrib3f wrap_glVertexAttrib3f
+#define glVertexAttrib3fv wrap_glVertexAttrib3fv
+#define glVertexAttrib4f wrap_glVertexAttrib4f
+#define glVertexAttrib4fv wrap_glVertexAttrib4fv
+#define glVertexAttribBinding wrap_glVertexAttribBinding
+#define glVertexAttribDivisor wrap_glVertexAttribDivisor
+#define glVertexAttribDivisorANGLE wrap_glVertexAttribDivisorANGLE
+#define glVertexAttribDivisorEXT wrap_glVertexAttribDivisorEXT
+#define glVertexAttribDivisorNV wrap_glVertexAttribDivisorNV
+#define glVertexAttribFormat wrap_glVertexAttribFormat
+#define glVertexAttribI4i wrap_glVertexAttribI4i
+#define glVertexAttribI4iv wrap_glVertexAttribI4iv
+#define glVertexAttribI4ui wrap_glVertexAttribI4ui
+#define glVertexAttribI4uiv wrap_glVertexAttribI4uiv
+#define glVertexAttribIFormat wrap_glVertexAttribIFormat
+#define glVertexAttribIPointer wrap_glVertexAttribIPointer
+#define glVertexAttribPointer wrap_glVertexAttribPointer
+#define glVertexBindingDivisor wrap_glVertexBindingDivisor
+#define glVertexPointer wrap_glVertexPointer
+#define glViewport wrap_glViewport
+#define glViewportArrayvNV wrap_glViewportArrayvNV
+#define glViewportIndexedfNV wrap_glViewportIndexedfNV
+#define glViewportIndexedfvNV wrap_glViewportIndexedfvNV
+#define glWaitSync wrap_glWaitSync
+#define glWaitSyncAPPLE wrap_glWaitSyncAPPLE
+#define glWeightPathsNV wrap_glWeightPathsNV
+#define glWeightPointerOES wrap_glWeightPointerOES
+
+#endif // HWUI_GLES_WRAP_ENABLED
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 75dcf16..81363d9 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -241,7 +241,7 @@
     const Glop::Mesh::Indices& indices = mesh.indices;
     const Glop::Fill& fill = glop.fill;
 
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
 
     // ---------------------------------------------
     // ---------- Program + uniform setup ----------
@@ -286,7 +286,7 @@
                 roundedOutRadius);
     }
 
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
 
     // --------------------------------
     // ---------- Mesh setup ----------
@@ -339,7 +339,7 @@
     // Shader uniforms
     SkiaShader::apply(*mCaches, fill.skiaShaderData);
 
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
     Texture* texture = (fill.skiaShaderData.skiaShaderType & kBitmap_SkiaShaderType) ?
             fill.skiaShaderData.bitmapData.bitmapTexture : nullptr;
     const AutoTexture autoCleanup(texture);
@@ -349,7 +349,7 @@
     // ------------------------------------
     blend().setFactors(glop.blend.src, glop.blend.dst);
 
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
 
     // ------------------------------------
     // ---------- Actual drawing ----------
@@ -379,7 +379,7 @@
         glDrawArrays(mesh.primitiveMode, 0, mesh.elementCount);
     }
 
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
 
     // -----------------------------------
     // ---------- Mesh teardown ----------
@@ -391,7 +391,7 @@
         glDisableVertexAttribArray(colorLocation);
     }
 
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
 }
 
 void RenderState::dump() {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 6f8d627..e7cf3ec 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -19,6 +19,7 @@
 
 #include "AnimationContext.h"
 #include "Caches.h"
+#include "Canvas.h"
 #include "DeferredLayerUpdater.h"
 #include "EglManager.h"
 #include "LayerUpdateQueue.h"
@@ -214,13 +215,13 @@
         // node(s) are non client / filler nodes.
         info.mode = (node.get() == target ? TreeInfo::MODE_FULL : TreeInfo::MODE_RT_ONLY);
         node->prepareTree(info);
-        GL_CHECKPOINT();
+        GL_CHECKPOINT(MODERATE);
     }
     mAnimationContext->runRemainingAnimations(info);
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
 
     freePrefetechedLayers();
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(MODERATE);
 
     if (CC_UNLIKELY(!mNativeWindow.get())) {
         mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
@@ -344,7 +345,7 @@
 
 #if HWUI_NEW_OPS
     FrameBuilder frameBuilder(mLayerUpdateQueue, dirty, frame.width(), frame.height(),
-            mRenderNodes, mLightCenter);
+            mRenderNodes, mLightCenter, mContentDrawBounds);
     mLayerUpdateQueue.clear();
     BakedOpRenderer renderer(Caches::getInstance(), mRenderThread.renderState(),
             mOpaque, mLightInfo);
@@ -394,7 +395,7 @@
             backdropBounds.doIntersect(targetBounds);
             // Check if we have to draw something on the left side ...
             if (targetBounds.left < contentBounds.left) {
-                mCanvas->save(SkCanvas::kClip_SaveFlag);
+                mCanvas->save(SaveFlags::Clip);
                 if (mCanvas->clipRect(targetBounds.left, targetBounds.top,
                                       contentBounds.left, targetBounds.bottom,
                                       SkRegion::kIntersect_Op)) {
@@ -407,7 +408,7 @@
             // ... or on the right side ...
             if (targetBounds.right > contentBounds.right &&
                 !targetBounds.isEmpty()) {
-                mCanvas->save(SkCanvas::kClip_SaveFlag);
+                mCanvas->save(SaveFlags::Clip);
                 if (mCanvas->clipRect(contentBounds.right, targetBounds.top,
                                       targetBounds.right, targetBounds.bottom,
                                       SkRegion::kIntersect_Op)) {
@@ -420,7 +421,7 @@
             // ... or at the top ...
             if (targetBounds.top < contentBounds.top &&
                 !targetBounds.isEmpty()) {
-                mCanvas->save(SkCanvas::kClip_SaveFlag);
+                mCanvas->save(SaveFlags::Clip);
                 if (mCanvas->clipRect(targetBounds.left, targetBounds.top, targetBounds.right,
                                       contentBounds.top,
                                       SkRegion::kIntersect_Op)) {
@@ -433,7 +434,7 @@
             // ... or at the bottom.
             if (targetBounds.bottom > contentBounds.bottom &&
                 !targetBounds.isEmpty()) {
-                mCanvas->save(SkCanvas::kClip_SaveFlag);
+                mCanvas->save(SaveFlags::Clip);
                 if (mCanvas->clipRect(targetBounds.left, contentBounds.bottom, targetBounds.right,
                                       targetBounds.bottom, SkRegion::kIntersect_Op)) {
                     mCanvas->drawRenderNode(node.get(), outBounds);
@@ -442,7 +443,7 @@
             }
         } else if (layer == 1) { // Content
             // It gets cropped against the bounds of the backdrop to stay inside.
-            mCanvas->save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
+            mCanvas->save(SaveFlags::MatrixClip);
 
             // We shift and clip the content to match its final location in the window.
             const float left = mContentDrawBounds.left;
@@ -468,7 +469,7 @@
     bool drew = mCanvas->finish();
 #endif
 
-    GL_CHECKPOINT();
+    GL_CHECKPOINT(LOW);
 
     // Even if we decided to cancel the frame, from the perspective of jank
     // metrics the frame was swapped at this point
@@ -505,6 +506,9 @@
 
     mJankTracker.addFrame(*mCurrentFrameInfo);
     mRenderThread.jankTracker().addFrame(*mCurrentFrameInfo);
+    if (CC_UNLIKELY(mFrameStatsReporter.get() != nullptr)) {
+        mFrameStatsReporter->reportFrameStats(mCurrentFrameInfo->data());
+    }
 
     GpuMemoryTracker::onFrameCompleted();
 }
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 8e64cbb..270fb1f 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -20,6 +20,7 @@
 #include "DamageAccumulator.h"
 #include "FrameInfo.h"
 #include "FrameInfoVisualizer.h"
+#include "FrameStatsReporter.h"
 #include "IContextFactory.h"
 #include "LayerUpdateQueue.h"
 #include "RenderNode.h"
@@ -139,6 +140,31 @@
         return mRenderThread.renderState();
     }
 
+    void addFrameStatsObserver(FrameStatsObserver* observer) {
+        if (mFrameStatsReporter.get() == nullptr) {
+            mFrameStatsReporter.reset(new FrameStatsReporter());
+        }
+
+        mFrameStatsReporter->addObserver(observer);
+    }
+
+    void removeFrameStatsObserver(FrameStatsObserver* observer) {
+        if (mFrameStatsReporter.get() != nullptr) {
+            mFrameStatsReporter->removeObserver(observer);
+            if (!mFrameStatsReporter->hasObservers()) {
+                mFrameStatsReporter.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
@@ -187,6 +213,7 @@
     std::string mName;
     JankTracker mJankTracker;
     FrameInfoVisualizer mProfiler;
+    std::unique_ptr<FrameStatsReporter> mFrameStatsReporter;
 
     std::set<RenderNode*> mPrefetechedLayers;
 
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index db2a2c8..1d1b144 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -568,6 +568,54 @@
     post(task);
 }
 
+CREATE_BRIDGE2(addFrameStatsObserver, CanvasContext* context,
+        FrameStatsObserver* frameStatsObserver) {
+   args->context->addFrameStatsObserver(args->frameStatsObserver);
+   if (args->frameStatsObserver != nullptr) {
+       args->frameStatsObserver->decStrong(args->context);
+   }
+   return nullptr;
+}
+
+void RenderProxy::addFrameStatsObserver(FrameStatsObserver* observer) {
+    SETUP_TASK(addFrameStatsObserver);
+    args->context = mContext;
+    args->frameStatsObserver = observer;
+    if (observer != nullptr) {
+        observer->incStrong(mContext);
+    }
+    post(task);
+}
+
+CREATE_BRIDGE2(removeFrameStatsObserver, CanvasContext* context,
+        FrameStatsObserver* frameStatsObserver) {
+   args->context->removeFrameStatsObserver(args->frameStatsObserver);
+   if (args->frameStatsObserver != nullptr) {
+       args->frameStatsObserver->decStrong(args->context);
+   }
+   return nullptr;
+}
+
+void RenderProxy::removeFrameStatsObserver(FrameStatsObserver* observer) {
+    SETUP_TASK(removeFrameStatsObserver);
+    args->context = mContext;
+    args->frameStatsObserver = observer;
+    if (observer != nullptr) {
+        observer->incStrong(mContext);
+    }
+    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 0f91b2a..4180d802 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -29,6 +29,7 @@
 #include <utils/StrongPointer.h>
 
 #include "../Caches.h"
+#include "../FrameStatsObserver.h"
 #include "../IContextFactory.h"
 #include "CanvasContext.h"
 #include "DrawFrameTask.h"
@@ -112,6 +113,10 @@
     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 long getDroppedFrameReportCount();
+
 private:
     RenderThread& mRenderThread;
     CanvasContext* mContext;
diff --git a/libs/hwui/tests/common/scenes/ClippingAnimation.cpp b/libs/hwui/tests/common/scenes/ClippingAnimation.cpp
index db6402c..a5fd712 100644
--- a/libs/hwui/tests/common/scenes/ClippingAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ClippingAnimation.cpp
@@ -32,7 +32,7 @@
         canvas.drawColor(Color::White, SkXfermode::kSrcOver_Mode);
         card = TestUtils::createNode(0, 0, 200, 400,
                 [](RenderProperties& props, TestCanvas& canvas) {
-            canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+            canvas.save(SaveFlags::MatrixClip);
             {
                 canvas.clipRect(0, 0, 200, 200, SkRegion::kIntersect_Op);
                 canvas.translate(100, 100);
@@ -43,7 +43,7 @@
             }
             canvas.restore();
 
-            canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+            canvas.save(SaveFlags::MatrixClip);
             {
                 SkPath clipCircle;
                 clipCircle.addCircle(100, 300, 100);
diff --git a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
index c899850..6904bec 100644
--- a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
@@ -34,18 +34,18 @@
         card = TestUtils::createNode(0, 0, 400, 800,
                 [](RenderProperties& props, TestCanvas& canvas) {
             // nested clipped saveLayers
-            canvas.saveLayerAlpha(0, 0, 400, 400, 200, SkCanvas::kClipToLayer_SaveFlag);
+            canvas.saveLayerAlpha(0, 0, 400, 400, 200, SaveFlags::ClipToLayer);
             canvas.drawColor(Color::Green_700, SkXfermode::kSrcOver_Mode);
             canvas.clipRect(50, 50, 350, 350, SkRegion::kIntersect_Op);
-            canvas.saveLayerAlpha(100, 100, 300, 300, 128, SkCanvas::kClipToLayer_SaveFlag);
+            canvas.saveLayerAlpha(100, 100, 300, 300, 128, SaveFlags::ClipToLayer);
             canvas.drawColor(Color::Blue_500, SkXfermode::kSrcOver_Mode);
             canvas.restore();
             canvas.restore();
 
             // single unclipped saveLayer
-            canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+            canvas.save(SaveFlags::MatrixClip);
             canvas.translate(0, 400);
-            canvas.saveLayerAlpha(100, 100, 300, 300, 128, SkCanvas::SaveFlags(0)); // unclipped
+            canvas.saveLayerAlpha(100, 100, 300, 300, 128, SaveFlags::Flags(0)); // unclipped
             SkPaint paint;
             paint.setAntiAlias(true);
             paint.setColor(Color::Green_700);
diff --git a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
index 0cba344..6d27c9d 100644
--- a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
@@ -69,7 +69,7 @@
             float cellSize = floorf(width / 7 - cellSpace);
 
             // each combination of strokeWidth + style gets a column
-            int outerCount = canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+            int outerCount = canvas.save(SaveFlags::MatrixClip);
             SkPaint paint;
             paint.setAntiAlias(true);
             SkPaint::Style styles[] = {
@@ -79,9 +79,9 @@
                 for (auto strokeWidth : { 0.0f, 0.5f, 8.0f }) {
                     paint.setStrokeWidth(strokeWidth);
                     // fill column with each op
-                    int middleCount = canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+                    int middleCount = canvas.save(SaveFlags::MatrixClip);
                     for (auto op : ops) {
-                        int innerCount = canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+                        int innerCount = canvas.save(SaveFlags::MatrixClip);
                         canvas.clipRect(0, 0, cellSize, cellSize, SkRegion::kIntersect_Op);
                         canvas.drawColor(Color::White, SkXfermode::Mode::kSrcOver_Mode);
                         op(canvas, cellSize, paint);
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index 2e59eb4..83af148 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -78,8 +78,8 @@
     StartBenchmarkTiming();
     for (int i = 0; i < iters; ++i) {
         canvas.reset(100, 100);
-        canvas.save(SkCanvas::kMatrixClip_SaveFlag);
-        canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
+        canvas.save(SaveFlags::MatrixClip);
         MicroBench::DoNotOptimize(&canvas);
         canvas.restore();
         canvas.restore();
@@ -121,12 +121,12 @@
     for (int i = 0; i < iters; ++i) {
         canvas.reset(100, 100);
         {
-            canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+            canvas.save(SaveFlags::MatrixClip);
             canvas.drawRect(0, 0, 100, 100, rectPaint);
             canvas.restore();
         }
         {
-            canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+            canvas.save(SaveFlags::MatrixClip);
             canvas.translate(10, 10);
             canvas.drawBitmap(iconBitmap, 0, 0, nullptr);
             canvas.restore();
@@ -151,8 +151,8 @@
 
     StartBenchmarkTiming();
     for (int i = 0; i < iters; ++i) {
-        state.save(SkCanvas::kMatrixClip_SaveFlag);
-        state.save(SkCanvas::kMatrixClip_SaveFlag);
+        state.save(SaveFlags::MatrixClip);
+        state.save(SaveFlags::MatrixClip);
         MicroBench::DoNotOptimize(&state);
         state.restore();
         state.restore();
diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
index 67c95e2..f9c2b67 100644
--- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp
+++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
@@ -47,7 +47,7 @@
 
         // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
         // Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         for (int i = 0; i < 30; i++) {
             canvas.translate(0, 10);
             canvas.drawRect(0, 0, 10, 10, paint);
diff --git a/libs/hwui/tests/unit/BufferPoolTests.cpp b/libs/hwui/tests/unit/BufferPoolTests.cpp
new file mode 100644
index 0000000..44e6d3a
--- /dev/null
+++ b/libs/hwui/tests/unit/BufferPoolTests.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/CanvasStateTests.cpp b/libs/hwui/tests/unit/CanvasStateTests.cpp
index 4df2687..68d74ee 100644
--- a/libs/hwui/tests/unit/CanvasStateTests.cpp
+++ b/libs/hwui/tests/unit/CanvasStateTests.cpp
@@ -16,6 +16,7 @@
 
 #include "CanvasState.h"
 
+#include "Canvas.h"
 #include "Matrix.h"
 #include "Rect.h"
 #include "utils/LinearAllocator.h"
@@ -23,7 +24,6 @@
 #include <gtest/gtest.h>
 #include <SkPath.h>
 #include <SkRegion.h>
-#include <SkCanvas.h>
 
 namespace android {
 namespace uirenderer {
@@ -83,7 +83,7 @@
     state.initializeSaveStack(200, 200,
             0, 0, 200, 200, Vector3());
 
-    state.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
+    state.save(SaveFlags::MatrixClip);
     {
         // rotated clip causes complex clip
         state.rotate(10);
@@ -93,7 +93,7 @@
     }
     state.restore();
 
-    state.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
+    state.save(SaveFlags::MatrixClip);
     {
         // subtracted clip causes complex clip
         EXPECT_TRUE(state.clipIsSimple());
@@ -102,7 +102,7 @@
     }
     state.restore();
 
-    state.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
+    state.save(SaveFlags::MatrixClip);
     {
         // complex path causes complex clip
         SkPath path;
@@ -119,7 +119,7 @@
     state.initializeSaveStack(200, 200,
             0, 0, 200, 200, Vector3());
 
-    state.save(SkCanvas::kClip_SaveFlag);
+    state.save(SaveFlags::Clip);
     {
         state.clipRect(0, 0, 10, 10, SkRegion::kIntersect_Op);
         ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10));
@@ -129,7 +129,7 @@
 
     Matrix4 simpleTranslate;
     simpleTranslate.loadTranslate(10, 10, 0);
-    state.save(SkCanvas::kMatrix_SaveFlag);
+    state.save(SaveFlags::Matrix);
     {
         state.translate(10, 10, 0);
         EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate));
@@ -143,7 +143,7 @@
     state.initializeSaveStack(200, 200,
             0, 0, 200, 200, Vector3());
 
-    state.save(SkCanvas::kMatrix_SaveFlag); // NOTE: clip not saved
+    state.save(SaveFlags::Matrix); // NOTE: clip not saved
     {
         state.clipRect(0, 0, 10, 10, SkRegion::kIntersect_Op);
         ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10));
@@ -153,7 +153,7 @@
 
     Matrix4 simpleTranslate;
     simpleTranslate.loadTranslate(10, 10, 0);
-    state.save(SkCanvas::kClip_SaveFlag); // NOTE: matrix not saved
+    state.save(SaveFlags::Clip); // NOTE: matrix not saved
     {
         state.translate(10, 10, 0);
         EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate));
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index b51bd2f..618df14 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -167,7 +167,7 @@
 TEST(FrameBuilder, simpleRejection) {
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.clipRect(200, 200, 400, 400, SkRegion::kIntersect_Op); // intersection should be empty
         canvas.drawRect(0, 0, 400, 400, SkPaint());
         canvas.restore();
@@ -198,7 +198,7 @@
 
         // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
         // Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         for (int i = 0; i < LOOPS; i++) {
             canvas.translate(0, 10);
             canvas.drawRect(0, 0, 10, 10, SkPaint());
@@ -215,7 +215,8 @@
             << "Expect number of ops = 2 * loop count";
 }
 
-TEST(FrameBuilder, clippedMerging) {
+// TODO: Disabled due to b/26793764
+TEST(FrameBuilder, DISABLED_clippedMerging) {
     class ClippedMergingTestRenderer : public TestRendererBase {
     public:
         void onMergedBitmapOps(const MergedBakedOpList& opList) override {
@@ -336,7 +337,7 @@
 
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.clipRect(50, 50, 150, 150, SkRegion::kIntersect_Op);
         canvas.drawLayer(layerUpdater.get());
         canvas.restore();
@@ -380,7 +381,7 @@
         paint.setColor(SK_ColorDKGRAY);
         canvas.drawRect(0, 0, 200, 200, paint);
 
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.translate(40, 40);
         canvas.drawRenderNode(child.get());
         canvas.restore();
@@ -448,7 +449,7 @@
 
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10, 10, 190, 190, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.saveLayerAlpha(10, 10, 190, 190, 128, SaveFlags::ClipToLayer);
         canvas.drawRect(10, 10, 190, 190, SkPaint());
         canvas.restore();
     });
@@ -512,10 +513,10 @@
 
     auto node = TestUtils::createNode(0, 0, 800, 800,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(0, 0, 800, 800, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.saveLayerAlpha(0, 0, 800, 800, 128, SaveFlags::ClipToLayer);
         {
             canvas.drawRect(0, 0, 800, 800, SkPaint());
-            canvas.saveLayerAlpha(0, 0, 400, 400, 128, SkCanvas::kClipToLayer_SaveFlag);
+            canvas.saveLayerAlpha(0, 0, 400, 400, 128, SaveFlags::ClipToLayer);
             {
                 canvas.drawRect(0, 0, 400, 400, SkPaint());
             }
@@ -534,9 +535,9 @@
 TEST(FrameBuilder, saveLayer_contentRejection) {
         auto node = TestUtils::createNode(0, 0, 200, 200,
                 [](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.clipRect(200, 200, 400, 400, SkRegion::kIntersect_Op);
-        canvas.saveLayerAlpha(200, 200, 400, 400, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.saveLayerAlpha(200, 200, 400, 400, 128, SaveFlags::ClipToLayer);
 
         // draw within save layer may still be recorded, but shouldn't be drawn
         canvas.drawRect(200, 200, 400, 400, SkPaint());
@@ -583,7 +584,7 @@
 
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10, 10, 190, 190, 128, (SkCanvas::SaveFlags)(0));
+        canvas.saveLayerAlpha(10, 10, 190, 190, 128, (SaveFlags::Flags)(0));
         canvas.drawRect(0, 0, 200, 200, SkPaint());
         canvas.restore();
     });
@@ -632,12 +633,12 @@
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
 
-        int restoreTo = canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+        int restoreTo = canvas.save(SaveFlags::MatrixClip);
         canvas.scale(2, 2);
-        canvas.saveLayerAlpha(0, 0, 5, 5, 128, SkCanvas::kMatrixClip_SaveFlag);
-        canvas.saveLayerAlpha(95, 0, 100, 5, 128, SkCanvas::kMatrixClip_SaveFlag);
-        canvas.saveLayerAlpha(0, 95, 5, 100, 128, SkCanvas::kMatrixClip_SaveFlag);
-        canvas.saveLayerAlpha(95, 95, 100, 100, 128, SkCanvas::kMatrixClip_SaveFlag);
+        canvas.saveLayerAlpha(0, 0, 5, 5, 128, SaveFlags::MatrixClip);
+        canvas.saveLayerAlpha(95, 0, 100, 5, 128, SaveFlags::MatrixClip);
+        canvas.saveLayerAlpha(0, 95, 5, 100, 128, SaveFlags::MatrixClip);
+        canvas.saveLayerAlpha(95, 95, 100, 100, 128, SaveFlags::MatrixClip);
         canvas.drawRect(0, 0, 100, 100, SkPaint());
         canvas.restoreToCount(restoreTo);
     });
@@ -695,9 +696,9 @@
 
     auto node = TestUtils::createNode(0, 0, 600, 600, // 500x500 triggers clipping
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(0, 0, 500, 500, 128, (SkCanvas::SaveFlags)0); // unclipped
-        canvas.saveLayerAlpha(100, 100, 400, 400, 128, SkCanvas::kClipToLayer_SaveFlag); // clipped
-        canvas.saveLayerAlpha(200, 200, 300, 300, 128, (SkCanvas::SaveFlags)0); // unclipped
+        canvas.saveLayerAlpha(0, 0, 500, 500, 128, (SaveFlags::Flags)0); // unclipped
+        canvas.saveLayerAlpha(100, 100, 400, 400, 128, SaveFlags::ClipToLayer); // clipped
+        canvas.saveLayerAlpha(200, 200, 300, 300, 128, (SaveFlags::Flags)0); // unclipped
         canvas.drawRect(200, 200, 300, 300, SkPaint());
         canvas.restore();
         canvas.restore();
@@ -849,7 +850,7 @@
         paint.setColor(SK_ColorDKGRAY);
         canvas.drawRect(0, 0, 200, 200, paint);
 
-        canvas.saveLayerAlpha(50, 50, 150, 150, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.saveLayerAlpha(50, 50, 150, 150, 128, SaveFlags::ClipToLayer);
         canvas.drawRenderNode(childPtr);
         canvas.restore();
     });
@@ -987,7 +988,7 @@
     });
     auto parent = TestUtils::createNode(0, 0, 100, 100,
             [&receiverBackground, &child](RenderProperties& properties, RecordingCanvas& canvas) {
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.translate(-scrollX, -scrollY); // Apply scroll (note: bg undoes this internally)
         canvas.drawRenderNode(receiverBackground.get());
         canvas.drawRenderNode(child.get());
@@ -1071,7 +1072,7 @@
             [](RenderProperties& props, RecordingCanvas& canvas) {
         // save/restore outside of reorderBarrier, so they don't get moved out of place
         canvas.translate(20, 10);
-        int count = canvas.saveLayerAlpha(30, 50, 130, 150, 128, SkCanvas::kClipToLayer_SaveFlag);
+        int count = canvas.saveLayerAlpha(30, 50, 130, 150, 128, SaveFlags::ClipToLayer);
         canvas.insertReorderBarrier(true);
         canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
         canvas.insertReorderBarrier(false);
@@ -1111,7 +1112,7 @@
             [](RenderProperties& props, RecordingCanvas& canvas) {
         props.mutateLayerProperties().setType(LayerType::RenderLayer);
         canvas.insertReorderBarrier(true);
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.translate(20, 10);
         canvas.drawRenderNode(createWhiteRectShadowCaster(5.0f).get());
         canvas.restore();
diff --git a/libs/hwui/tests/unit/LeakCheckTests.cpp b/libs/hwui/tests/unit/LeakCheckTests.cpp
index 41e44fc..4a635fb 100644
--- a/libs/hwui/tests/unit/LeakCheckTests.cpp
+++ b/libs/hwui/tests/unit/LeakCheckTests.cpp
@@ -32,7 +32,7 @@
 RENDERTHREAD_TEST(LeakCheck, saveLayerUnclipped_simple) {
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10, 10, 190, 190, 128, (SkCanvas::SaveFlags)(0));
+        canvas.saveLayerAlpha(10, 10, 190, 190, 128, (SaveFlags::Flags)(0));
         canvas.drawRect(0, 0, 200, 200, SkPaint());
         canvas.restore();
     });
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index ff098c8..01bfc5a 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -35,7 +35,7 @@
 
 TEST(RecordingCanvas, emptyPlayback) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.restore();
     });
     playbackOps(*dl, [](const RecordedOp& op) { ADD_FAILURE(); });
@@ -43,7 +43,7 @@
 
 TEST(RecordingCanvas, clipRect) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [](RecordingCanvas& canvas) {
-        canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.clipRect(0, 0, 100, 100, SkRegion::kIntersect_Op);
         canvas.drawRect(0, 0, 50, 50, SkPaint());
         canvas.drawRect(50, 50, 100, 100, SkPaint());
@@ -176,16 +176,16 @@
         SkPaint paint;
         paint.setColor(SK_ColorBLUE);
 
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         {
             // a background!
-            canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+            canvas.save(SaveFlags::MatrixClip);
             canvas.drawRect(0, 0, 100, 200, paint);
             canvas.restore();
         }
         {
             // an image!
-            canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+            canvas.save(SaveFlags::MatrixClip);
             canvas.translate(25, 25);
             canvas.scale(2, 2);
             canvas.drawBitmap(bitmap, 0, 0, nullptr);
@@ -224,7 +224,7 @@
 
 TEST(RecordingCanvas, saveLayer_simple) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10, 20, 190, 180, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.saveLayerAlpha(10, 20, 190, 180, 128, SaveFlags::ClipToLayer);
         canvas.drawRect(10, 20, 190, 180, SkPaint());
         canvas.restore();
     });
@@ -258,7 +258,7 @@
 
 TEST(RecordingCanvas, saveLayer_missingRestore) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(0, 0, 200, 200, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.saveLayerAlpha(0, 0, 200, 200, 128, SaveFlags::ClipToLayer);
         canvas.drawRect(0, 0, 200, 200, SkPaint());
         // Note: restore omitted, shouldn't result in unmatched save
     });
@@ -273,7 +273,7 @@
 
 TEST(RecordingCanvas, saveLayer_simpleUnclipped) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.saveLayerAlpha(10, 20, 190, 180, 128, (SkCanvas::SaveFlags)0); // unclipped
+        canvas.saveLayerAlpha(10, 20, 190, 180, 128, (SaveFlags::Flags)0); // unclipped
         canvas.drawRect(10, 20, 190, 180, SkPaint());
         canvas.restore();
     });
@@ -305,9 +305,9 @@
 
 TEST(RecordingCanvas, saveLayer_addClipFlag) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.clipRect(10, 20, 190, 180, SkRegion::kIntersect_Op);
-        canvas.saveLayerAlpha(10, 20, 190, 180, 128, (SkCanvas::SaveFlags)0); // unclipped
+        canvas.saveLayerAlpha(10, 20, 190, 180, 128, (SaveFlags::Flags)0); // unclipped
         canvas.drawRect(10, 20, 190, 180, SkPaint());
         canvas.restore();
         canvas.restore();
@@ -327,7 +327,7 @@
         // shouldn't matter, since saveLayer will clip to its bounds
         canvas.clipRect(-1000, -1000, 1000, 1000, SkRegion::kReplace_Op);
 
-        canvas.saveLayerAlpha(100, 100, 300, 300, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.saveLayerAlpha(100, 100, 300, 300, 128, SaveFlags::ClipToLayer);
         canvas.drawRect(0, 0, 400, 400, SkPaint());
         canvas.restore();
     });
@@ -348,12 +348,12 @@
 
 TEST(RecordingCanvas, saveLayer_rotateUnclipped) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.translate(100, 100);
         canvas.rotate(45);
         canvas.translate(-50, -50);
 
-        canvas.saveLayerAlpha(0, 0, 100, 100, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.saveLayerAlpha(0, 0, 100, 100, 128, SaveFlags::ClipToLayer);
         canvas.drawRect(0, 0, 100, 100, SkPaint());
         canvas.restore();
 
@@ -374,13 +374,13 @@
 
 TEST(RecordingCanvas, saveLayer_rotateClipped) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
-        canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+        canvas.save(SaveFlags::MatrixClip);
         canvas.translate(100, 100);
         canvas.rotate(45);
         canvas.translate(-200, -200);
 
         // area of saveLayer will be clipped to parent viewport, so we ask for 400x400...
-        canvas.saveLayerAlpha(0, 0, 400, 400, 128, SkCanvas::kClipToLayer_SaveFlag);
+        canvas.saveLayerAlpha(0, 0, 400, 400, 128, SaveFlags::ClipToLayer);
         canvas.drawRect(0, 0, 400, 400, SkPaint());
         canvas.restore();
 
diff --git a/libs/hwui/utils/GLUtils.cpp b/libs/hwui/utils/GLUtils.cpp
index 55104de..33209759 100644
--- a/libs/hwui/utils/GLUtils.cpp
+++ b/libs/hwui/utils/GLUtils.cpp
@@ -21,10 +21,19 @@
 
 #include "GLUtils.h"
 
+#if DEBUG_OPENGL >= DEBUG_LEVEL_HIGH && !defined(HWUI_GLES_WRAP_ENABLED)
+#error Setting DEBUG_OPENGL to HIGH requires setting HWUI_ENABLE_OPENGL_VALIDATION to true in the Android.mk!
+#endif
+
 namespace android {
 namespace uirenderer {
 
 bool GLUtils::dumpGLErrors() {
+#if DEBUG_OPENGL >= DEBUG_LEVEL_HIGH
+    // If DEBUG_LEVEL_HIGH is set then every GLES call is already wrapped
+    // and asserts that there was no error. So this can just return success.
+    return false;
+#else
     bool errorObserved = false;
     GLenum status = GL_NO_ERROR;
     while ((status = glGetError()) != GL_NO_ERROR) {
@@ -47,6 +56,7 @@
         }
     }
     return errorObserved;
+#endif
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/utils/GLUtils.h b/libs/hwui/utils/GLUtils.h
index 85a10f9..b49c1eb 100644
--- a/libs/hwui/utils/GLUtils.h
+++ b/libs/hwui/utils/GLUtils.h
@@ -23,17 +23,22 @@
 namespace android {
 namespace uirenderer {
 
+
 #if DEBUG_OPENGL
-#define GL_CHECKPOINT() LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(),\
-        "GL errors! %s:%d", __FILE__, __LINE__)
+#define GL_CHECKPOINT(LEVEL) \
+    do { if (DEBUG_OPENGL >= DEBUG_LEVEL_##LEVEL) {\
+    LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(),\
+            "GL errors! %s:%d", __FILE__, __LINE__);\
+    } } while (0)
 #else
-#define GL_CHECKPOINT()
+#define GL_CHECKPOINT(LEVEL)
 #endif
 
 class GLUtils {
 public:
     /**
      * Print out any GL errors with ALOGE, returns true if any errors were found.
+     * You probably want to use GL_CHECKPOINT(LEVEL) instead of calling this directly
      */
     static bool dumpGLErrors();
 
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index dcc4946..b0431ce 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -138,8 +138,8 @@
 
         // Move the pixels into the destination SkBitmap
 
-        SK_ALWAYSBREAK(nativeBuffer.format == android::PIXEL_FORMAT_RGBA_8888 &&
-                       "Native buffer not RGBA!");
+        LOG_ALWAYS_FATAL_IF(nativeBuffer.format != android::PIXEL_FORMAT_RGBA_8888,
+                            "Native buffer not RGBA!");
         SkImageInfo nativeConfig =
             SkImageInfo::Make(nativeBuffer.width, nativeBuffer.height,
                               kRGBA_8888_SkColorType, kPremul_SkAlphaType);
@@ -153,8 +153,8 @@
             return false;
         }
 
-        SK_ALWAYSBREAK(bmp->colorType() == kRGBA_8888_SkColorType &&
-                       "Destination buffer not RGBA!");
+        LOG_ALWAYS_FATAL_IF(bmp->colorType() != kRGBA_8888_SkColorType,
+                            "Destination buffer not RGBA!");
         success =
             nativeWrapper.readPixels(destinationConfig, bmp->getPixels(), bmp->rowBytes(), 0, 0);
         if (!success) {
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 0fba992..d9690f0 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -460,6 +460,11 @@
         public static final String FEATURE_TunneledPlayback       = "tunneled-playback";
 
         /**
+         * <b>video encoder only</b>: codec supports intra refresh.
+         */
+        public static final String FEATURE_IntraRefresh = "intra-refresh";
+
+        /**
          * Query codec feature capabilities.
          * <p>
          * These features are supported to be used by the codec.  These
@@ -486,6 +491,10 @@
             new Feature(FEATURE_TunneledPlayback, (1 << 2), false),
         };
 
+        private static final Feature[] encoderFeatures = {
+            new Feature(FEATURE_IntraRefresh, (1 << 0), false),
+        };
+
         /** @hide */
         public String[] validFeatures() {
             Feature[] features = getValidFeatures();
@@ -500,7 +509,7 @@
             if (!isEncoder()) {
                 return decoderFeatures;
             }
-            return new Feature[] {};
+            return encoderFeatures;
         }
 
         private boolean checkFeature(String name, int flags) {
@@ -1726,7 +1735,7 @@
         }
 
         private void applyLevelLimits() {
-            int maxBlocksPerSecond = 0;
+            long maxBlocksPerSecond = 0;
             int maxBlocks = 0;
             int maxBps = 0;
             int maxDPBBlocks = 0;
@@ -2052,11 +2061,11 @@
                         16 /* blockWidth */, 16 /* blockHeight */,
                         1 /* widthAlignment */, 1 /* heightAlignment */);
                 mFrameRateRange = Range.create(1, maxRate);
-            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) ||
-                    mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
-                maxBlocks = maxBlocksPerSecond = Integer.MAX_VALUE;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8)) {
+                maxBlocks = Integer.MAX_VALUE;
+                maxBlocksPerSecond = Integer.MAX_VALUE;
 
-                // TODO: set to 100Mbps for now, need a number for VPX
+                // TODO: set to 100Mbps for now, need a number for VP8
                 maxBps = 100000000;
 
                 // profile levels are not indicative for VPx, but verify
@@ -2084,11 +2093,80 @@
                     errors &= ~ERROR_NONE_SUPPORTED;
                 }
 
-                final int blockSize =
-                    mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) ? 16 : 8;
+                final int blockSize = 16;
                 applyMacroBlockLimits(Short.MAX_VALUE, Short.MAX_VALUE,
                         maxBlocks, maxBlocksPerSecond, blockSize, blockSize,
                         1 /* widthAlignment */, 1 /* heightAlignment */);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+                maxBlocksPerSecond = 829440;
+                maxBlocks = 36864;
+                maxBps = 200000;
+
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    long SR = 0;
+                    int FS = 0;
+                    int BR = 0;
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.VP9Level1:
+                            SR =      829440; FS =    36864; BR =    200; break;
+                        case CodecProfileLevel.VP9Level11:
+                            SR =     2764800; FS =    73728; BR =    800; break;
+                        case CodecProfileLevel.VP9Level2:
+                            SR =     4608000; FS =   122880; BR =   1800; break;
+                        case CodecProfileLevel.VP9Level21:
+                            SR =     9216000; FS =   245760; BR =   3600; break;
+                        case CodecProfileLevel.VP9Level3:
+                            SR =    20736000; FS =   552960; BR =   7200; break;
+                        case CodecProfileLevel.VP9Level31:
+                            SR =    36864000; FS =   983040; BR =  12000; break;
+                        case CodecProfileLevel.VP9Level4:
+                            SR =    83558400; FS =  2228224; BR =  18000; break;
+                        case CodecProfileLevel.VP9Level41:
+                            SR =   160432128; FS =  2228224; BR =  30000; break;
+                        case CodecProfileLevel.VP9Level5:
+                            SR =   311951360; FS =  8912896; BR =  60000; break;
+                        case CodecProfileLevel.VP9Level51:
+                            SR =   588251136; FS =  8912896; BR = 120000; break;
+                        case CodecProfileLevel.VP9Level52:
+                            SR =  1176502272; FS =  8912896; BR = 180000; break;
+                        case CodecProfileLevel.VP9Level6:
+                            SR =  1176502272; FS = 35651584; BR = 180000; break;
+                        case CodecProfileLevel.VP9Level61:
+                            SR = 2353004544L; FS = 35651584; BR = 240000; break;
+                        case CodecProfileLevel.VP9Level62:
+                            SR = 4706009088L; FS = 35651584; BR = 480000; break;
+                        default:
+                            Log.w(TAG, "Unrecognized level "
+                                    + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.VP9Profile0:
+                        case CodecProfileLevel.VP9Profile1:
+                        case CodecProfileLevel.VP9Profile2:
+                        case CodecProfileLevel.VP9Profile3:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    errors &= ~ERROR_NONE_SUPPORTED;
+                    maxBlocksPerSecond = Math.max(SR, maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR * 1000, maxBps);
+                }
+
+                final int blockSize = 8;
+                int maxLengthInBlocks = Utils.divUp(maxBlocks, blockSize);
+                maxBlocks = Utils.divUp(maxBlocks, blockSize * blockSize);
+                maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, blockSize * blockSize);
+
+                applyMacroBlockLimits(
+                        maxLengthInBlocks, maxLengthInBlocks,
+                        maxBlocks, maxBlocksPerSecond,
+                        blockSize, blockSize,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
             } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
                 maxBlocks = 36864;
                 maxBlocksPerSecond = maxBlocks * 15;
@@ -2531,6 +2609,28 @@
         // from OMX_VIDEO_VP8PROFILETYPE
         public static final int VP8ProfileMain = 0x01;
 
+        // from OMX_VIDEO_VP9PROFILETYPE
+        public static final int VP9Profile0 = 0x00;
+        public static final int VP9Profile1 = 0x01;
+        public static final int VP9Profile2 = 0x02;
+        public static final int VP9Profile3 = 0x03;
+
+        // from OMX_VIDEO_VP9LEVELTYPE
+        public static final int VP9Level1  = 0x0;
+        public static final int VP9Level11 = 0x1;
+        public static final int VP9Level2  = 0x2;
+        public static final int VP9Level21 = 0x4;
+        public static final int VP9Level3  = 0x8;
+        public static final int VP9Level31 = 0x10;
+        public static final int VP9Level4  = 0x20;
+        public static final int VP9Level41 = 0x40;
+        public static final int VP9Level5  = 0x80;
+        public static final int VP9Level51 = 0x100;
+        public static final int VP9Level52 = 0x200;
+        public static final int VP9Level6  = 0x400;
+        public static final int VP9Level61 = 0x800;
+        public static final int VP9Level62 = 0x1000;
+
         // from OMX_VIDEO_HEVCPROFILETYPE
         public static final int HEVCProfileMain   = 0x01;
         public static final int HEVCProfileMain10 = 0x02;
@@ -2563,17 +2663,40 @@
         public static final int HEVCMainTierLevel62 = 0x1000000;
         public static final int HEVCHighTierLevel62 = 0x2000000;
 
+        // from OMX_VIDEO_DOLBYVISIONPROFILETYPE
+        public static final int DolbyVisionProfileDvavDer = 0x1;
+        public static final int DolbyVisionProfileDvavDen = 0x2;
+        public static final int DolbyVisionProfileDvheDer = 0x3;
+        public static final int DolbyVisionProfileDvheDen = 0x4;
+        public static final int DolbyVisionProfileDvheDtr = 0x5;
+        public static final int DolbyVisionProfileDvheStn = 0x6;
+
+        // from OMX_VIDEO_DOLBYVISIONLEVELTYPE
+        public static final int DolbyVisionLevelHd24    = 0x1;
+        public static final int DolbyVisionLevelHd30    = 0x2;
+        public static final int DolbyVisionLevelFhd24   = 0x4;
+        public static final int DolbyVisionLevelFhd30   = 0x8;
+        public static final int DolbyVisionLevelFhd60   = 0x10;
+        public static final int DolbyVisionLevelUhd24   = 0x20;
+        public static final int DolbyVisionLevelUhd30   = 0x40;
+        public static final int DolbyVisionLevelUhd48   = 0x80;
+        public static final int DolbyVisionLevelUhd60   = 0x100;
+
         /**
          * Defined in the OpenMAX IL specs, depending on the type of media
          * this can be OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE,
-         * OMX_VIDEO_MPEG4PROFILETYPE or OMX_VIDEO_VP8PROFILETYPE.
+         * OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_VP8PROFILETYPE or OMX_VIDEO_VP9PROFILETYPE.
          */
         public int profile;
 
         /**
          * Defined in the OpenMAX IL specs, depending on the type of media
          * this can be OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE
-         * OMX_VIDEO_MPEG4LEVELTYPE or OMX_VIDEO_VP8LEVELTYPE.
+         * OMX_VIDEO_MPEG4LEVELTYPE, OMX_VIDEO_VP8LEVELTYPE or OMX_VIDEO_VP9LEVELTYPE.
+         *
+         * Note that VP9 decoder on platforms before {@link android.os.Build.VERSION_CODES#N} may
+         * not advertise a profile level support. For those VP9 decoders, please use
+         * {@link VideoCapabilities} to determine the codec capabilities.
          */
         public int level;
     };
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 7d76e74..f7becf5 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -91,8 +91,10 @@
     public static final int FILE_TYPE_RW2     = 305;
     public static final int FILE_TYPE_ORF     = 306;
     public static final int FILE_TYPE_RAF     = 307;
+    public static final int FILE_TYPE_PEF     = 308;
+    public static final int FILE_TYPE_SRW     = 309;
     private static final int FIRST_RAW_IMAGE_FILE_TYPE = FILE_TYPE_DNG;
-    private static final int LAST_RAW_IMAGE_FILE_TYPE = FILE_TYPE_RAF;
+    private static final int LAST_RAW_IMAGE_FILE_TYPE = FILE_TYPE_SRW;
 
     // Playlist file types
     public static final int FILE_TYPE_M3U      = 41;
@@ -228,17 +230,19 @@
         addFileType("GIF", FILE_TYPE_GIF, "image/gif", MtpConstants.FORMAT_GIF);
         addFileType("PNG", FILE_TYPE_PNG, "image/png", MtpConstants.FORMAT_PNG);
         addFileType("BMP", FILE_TYPE_BMP, "image/x-ms-bmp", MtpConstants.FORMAT_BMP);
-        addFileType("WBMP", FILE_TYPE_WBMP, "image/vnd.wap.wbmp");
-        addFileType("WEBP", FILE_TYPE_WEBP, "image/webp");
+        addFileType("WBMP", FILE_TYPE_WBMP, "image/vnd.wap.wbmp", MtpConstants.FORMAT_DEFINED);
+        addFileType("WEBP", FILE_TYPE_WEBP, "image/webp", MtpConstants.FORMAT_DEFINED);
 
         addFileType("DNG", FILE_TYPE_DNG, "image/x-adobe-dng", MtpConstants.FORMAT_DNG);
-        addFileType("CR2", FILE_TYPE_CR2, "image/x-canon-cr2");
-        addFileType("NEF", FILE_TYPE_NEF, "image/x-nikon-nef");
-        addFileType("NRW", FILE_TYPE_NRW, "image/x-nikon-nrw");
-        addFileType("ARW", FILE_TYPE_ARW, "image/x-sony-arw");
-        addFileType("RW2", FILE_TYPE_RW2, "image/x-panasonic-rw2");
-        addFileType("ORF", FILE_TYPE_ORF, "image/x-olympus-orf");
-        addFileType("RAF", FILE_TYPE_RAF, "image/x-fuji-raf");
+        addFileType("CR2", FILE_TYPE_CR2, "image/x-canon-cr2", MtpConstants.FORMAT_TIFF);
+        addFileType("NEF", FILE_TYPE_NEF, "image/x-nikon-nef", MtpConstants.FORMAT_TIFF_EP);
+        addFileType("NRW", FILE_TYPE_NRW, "image/x-nikon-nrw", MtpConstants.FORMAT_TIFF);
+        addFileType("ARW", FILE_TYPE_ARW, "image/x-sony-arw", MtpConstants.FORMAT_TIFF);
+        addFileType("RW2", FILE_TYPE_RW2, "image/x-panasonic-rw2", MtpConstants.FORMAT_TIFF);
+        addFileType("ORF", FILE_TYPE_ORF, "image/x-olympus-orf", MtpConstants.FORMAT_TIFF);
+        addFileType("RAF", FILE_TYPE_RAF, "image/x-fuji-raf", MtpConstants.FORMAT_DEFINED);
+        addFileType("PEF", FILE_TYPE_PEF, "image/x-pentax-pef", MtpConstants.FORMAT_TIFF);
+        addFileType("SRW", FILE_TYPE_SRW, "image/x-samsung-srw", MtpConstants.FORMAT_TIFF);
 
         addFileType("M3U", FILE_TYPE_M3U, "audio/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
         addFileType("M3U", FILE_TYPE_M3U, "application/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index abdf220..930d8b8 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -44,7 +44,8 @@
  *         for encoders, readable in the output format of decoders</b></td></tr>
  * <tr><td>{@link #KEY_FRAME_RATE}</td><td>Integer or Float</td><td><b>encoder-only</b></td></tr>
  * <tr><td>{@link #KEY_CAPTURE_RATE}</td><td>Integer</td><td></td></tr>
-* <tr><td>{@link #KEY_I_FRAME_INTERVAL}</td><td>Integer</td><td><b>encoder-only</b></td></tr>
+ * <tr><td>{@link #KEY_I_FRAME_INTERVAL}</td><td>Integer</td><td><b>encoder-only</b></td></tr>
+ * <tr><td>{@link #KEY_INTRA_REFRESH_PERIOD}</td><td>Integer</td><td><b>encoder-only</b>, optional</td></tr>
  * <tr><td>{@link #KEY_MAX_WIDTH}</td><td>Integer</td><td><b>decoder-only</b>, optional, max-resolution width</td></tr>
  * <tr><td>{@link #KEY_MAX_HEIGHT}</td><td>Integer</td><td><b>decoder-only</b>, optional, max-resolution height</td></tr>
  * <tr><td>{@link #KEY_REPEAT_PREVIOUS_FRAME_AFTER}</td><td>Long</td><td><b>video encoder in surface-mode only</b></td></tr>
@@ -218,6 +219,20 @@
     public static final String KEY_I_FRAME_INTERVAL = "i-frame-interval";
 
     /**
+    * An optional key describing the period of intra refresh in frames. This is an
+    * optional parameter that applies only to video encoders. If encoder supports it
+    * ({@link MediaCodecInfo.CodecCapabilities#FEATURE_IntraRefresh}), the whole
+    * frame is completely refreshed after the specified period. Also for each frame,
+    * a fix subset of macroblocks must be intra coded which leads to more constant bitrate
+    * than inserting a key frame. This key is recommended for video streaming applications
+    * as it provides low-delay and good error-resilience. This key is ignored if the
+    * video encoder does not support the intra refresh feature. Use the output format to
+    * verify that this feature was enabled.
+    * The associated value is an integer.
+    */
+    public static final String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period";
+
+   /**
      * A key describing the temporal layering schema.  This is an optional parameter
      * that applies only to video encoders.  Use {@link MediaCodec#getInputFormat}
      * after {@link MediaCodec#configure configure} to query if the encoder supports
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 504c6d0..f09f654 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -389,6 +389,7 @@
         public static final int H264 = 2;
         public static final int MPEG_4_SP = 3;
         public static final int VP8 = 4;
+        public static final int HEVC = 5;
     }
 
     /**
@@ -821,7 +822,6 @@
      *
      * @throws IllegalStateException if it is called before start() or after
      * stop()
-     * {@hide}
      */
     public native void pause() throws IllegalStateException;
 
@@ -832,7 +832,6 @@
      * @throws IllegalStateException if it is called before start() or after
      * stop()
      * @see android.media.MediaRecorder#pause
-     * {@hide}
      */
     public native void resume() throws IllegalStateException;
 
diff --git a/media/java/android/media/Utils.java b/media/java/android/media/Utils.java
index 2cd3c43..35b083e 100644
--- a/media/java/android/media/Utils.java
+++ b/media/java/android/media/Utils.java
@@ -174,7 +174,7 @@
         return (num + den - 1) / den;
     }
 
-    private static long divUp(long num, long den) {
+    static long divUp(long num, long den) {
         return (num + den - 1) / den;
     }
 
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 4ca89a8..869512d 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -34,9 +34,9 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
-import android.service.media.MediaBrowserService;
 import android.service.media.IMediaBrowserService;
 import android.service.media.IMediaBrowserServiceCallbacks;
+import android.service.media.MediaBrowserService;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -44,7 +44,9 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map.Entry;
 
 /**
  * Browses media content offered by a link MediaBrowserService.
@@ -52,11 +54,39 @@
  * This object is not thread-safe. All calls should happen on the thread on which the browser
  * was constructed.
  * </p>
+ * <h3>Standard Extra Data</h3>
+ *
+ * <p>These are the current standard fields that can be used as extra data via
+ * {@link #subscribe(String, Bundle, SubscriptionCallback)}, {@link #unsubscribe(String, Bundle)},
+ * and {@link SubscriptionCallback#onChildrenLoaded(String, List, Bundle)}.
+ *
+ * <ul>
+ *     <li> {@link #EXTRA_PAGE}
+ *     <li> {@link #EXTRA_PAGE_SIZE}
+ * </ul>
  */
 public final class MediaBrowser {
     private static final String TAG = "MediaBrowser";
     private static final boolean DBG = false;
 
+    /**
+     * Used as an int extra field to denote the page number to subscribe.
+     * The value of {@code EXTRA_PAGE} should be greater than or equal to 1.
+     *
+     * @see android.service.media.MediaBrowserService.BrowserRoot
+     * @see #EXTRA_PAGE_SIZE
+     */
+    public static final String EXTRA_PAGE = "android.media.browse.extra.PAGE";
+
+    /**
+     * Used as an int extra field to denote the number of media items in a page.
+     * The value of {@code EXTRA_PAGE_SIZE} should be greater than or equal to 1.
+     *
+     * @see android.service.media.MediaBrowserService.BrowserRoot
+     * @see #EXTRA_PAGE
+     */
+    public static final String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
+
     private static final int CONNECT_STATE_DISCONNECTED = 0;
     private static final int CONNECT_STATE_CONNECTING = 1;
     private static final int CONNECT_STATE_CONNECTED = 2;
@@ -67,8 +97,7 @@
     private final ConnectionCallback mCallback;
     private final Bundle mRootHints;
     private final Handler mHandler = new Handler();
-    private final ArrayMap<String,Subscription> mSubscriptions =
-            new ArrayMap<String, MediaBrowser.Subscription>();
+    private final ArrayMap<String, Subscription> mSubscriptions = new ArrayMap<>();
 
     private int mState = CONNECT_STATE_DISCONNECTED;
     private MediaServiceConnection mServiceConnection;
@@ -291,7 +320,7 @@
      * the specified id and subscribes to receive updates when they change.
      * <p>
      * The list of subscriptions is maintained even when not connected and is
-     * restored after reconnection. It is ok to subscribe while not connected
+     * restored after the reconnection. It is ok to subscribe while not connected
      * but the results will not be returned until the connection completes.
      * </p>
      * <p>
@@ -305,34 +334,37 @@
      * @param callback The callback to receive the list of children.
      */
     public void subscribe(@NonNull String parentId, @NonNull SubscriptionCallback callback) {
-        // Check arguments.
-        if (parentId == null) {
-            throw new IllegalArgumentException("parentId is null");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback is null");
-        }
+        subscribeInternal(parentId, null, callback);
+    }
 
-        // Update or create the subscription.
-        Subscription sub = mSubscriptions.get(parentId);
-        boolean newSubscription = sub == null;
-        if (newSubscription) {
-            sub = new Subscription(parentId);
-            mSubscriptions.put(parentId, sub);
+    /**
+     * Queries with service-specific arguments for information about the media items
+     * that are contained within the specified id and subscribes to receive updates
+     * when they change.
+     * <p>
+     * The list of subscriptions is maintained even when not connected and is
+     * restored after the reconnection. It is ok to subscribe while not connected
+     * but the results will not be returned until the connection completes.
+     * </p>
+     * <p>
+     * If the id is already subscribed with a different callback then the new
+     * callback will replace the previous one and the child data will be
+     * reloaded.
+     * </p>
+     *
+     * @param parentId The id of the parent media item whose list of children
+     *            will be subscribed.
+     * @param options A bundle of service-specific arguments to send to the media
+     *            browse service. The contents of this bundle may affect the
+     *            information returned when browsing.
+     * @param callback The callback to receive the list of children.
+     */
+    public void subscribe(@NonNull String parentId, @NonNull Bundle options,
+            @NonNull SubscriptionCallback callback) {
+        if (options == null) {
+            throw new IllegalArgumentException("options are null");
         }
-        sub.callback = 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.
-        if (mState == CONNECT_STATE_CONNECTED) {
-            try {
-                mServiceBinder.addSubscription(parentId, mServiceCallbacks);
-            } catch (RemoteException ex) {
-                // Process is crashing.  We will disconnect, and upon reconnect we will
-                // automatically reregister. So nothing to do here.
-                Log.d(TAG, "addSubscription failed with RemoteException parentId=" + parentId);
-            }
-        }
+        subscribeInternal(parentId, options, callback);
     }
 
     /**
@@ -343,27 +375,28 @@
      * </p>
      *
      * @param parentId The id of the parent media item whose list of children
-     * will be unsubscribed.
+     *            will be unsubscribed.
      */
     public void unsubscribe(@NonNull String parentId) {
-        // Check arguments.
-        if (TextUtils.isEmpty(parentId)) {
-            throw new IllegalArgumentException("parentId is empty.");
-        }
+        unsubscribeInternal(parentId, null);
+    }
 
-        // Remove from our list.
-        final Subscription sub = mSubscriptions.remove(parentId);
-
-        // Tell the service if necessary.
-        if (mState == CONNECT_STATE_CONNECTED && sub != null) {
-            try {
-                mServiceBinder.removeSubscription(parentId, mServiceCallbacks);
-            } catch (RemoteException ex) {
-                // Process is crashing.  We will disconnect, and upon reconnect we will
-                // automatically reregister. So nothing to do here.
-                Log.d(TAG, "removeSubscription failed with RemoteException parentId=" + parentId);
-            }
+    /**
+     * Unsubscribes for changes to the children of the specified media id.
+     * <p>
+     * The query callback will no longer be invoked for results associated with
+     * this id once this method returns.
+     * </p>
+     *
+     * @param parentId The id of the parent media item whose list of children
+     *            will be unsubscribed.
+     * @param options A bundle sent to the media browse service to subscribe.
+     */
+    public void unsubscribe(@NonNull String parentId, @NonNull Bundle options) {
+        if (options == null) {
+            throw new IllegalArgumentException("options are null");
         }
+        unsubscribeInternal(parentId, options);
     }
 
     /**
@@ -420,6 +453,73 @@
         }
     }
 
+    private void subscribeInternal(String parentId, Bundle options, SubscriptionCallback callback) {
+        // Check arguments.
+        if (parentId == null) {
+            throw new IllegalArgumentException("parentId is null");
+        }
+        if (callback == null) {
+            throw new IllegalArgumentException("callback is null");
+        }
+        // Update or create the subscription.
+        Subscription sub = mSubscriptions.get(parentId);
+        if (sub == null) {
+            sub = new Subscription();
+            mSubscriptions.put(parentId, sub);
+        }
+        sub.add(callback, options);
+
+        // If we are connected, tell the service that we are watching. If we aren't connected,
+        // the service will be told when we connect.
+        if (mState == CONNECT_STATE_CONNECTED) {
+            try {
+                // NOTE: In order not to break the behavior of the support library, call
+                // addSubscription instead of addSubscriptionWithOptions when the options are null.
+                if (options == null) {
+                    mServiceBinder.addSubscription(parentId, mServiceCallbacks);
+                } else {
+                    mServiceBinder.addSubscriptionWithOptions(parentId, options, mServiceCallbacks);
+                }
+            } catch (RemoteException ex) {
+                // Process is crashing. We will disconnect, and upon reconnect we will
+                // automatically reregister. So nothing to do here.
+                Log.d(TAG, "addSubscription failed with RemoteException parentId=" + parentId);
+            }
+        }
+    }
+
+    private void unsubscribeInternal(String parentId, Bundle options) {
+        // Check arguments.
+        if (TextUtils.isEmpty(parentId)) {
+            throw new IllegalArgumentException("parentId is empty.");
+        }
+
+        // Remove from our list.
+        Subscription sub = mSubscriptions.get(parentId);
+
+        // Tell the service if necessary.
+        if (sub != null && sub.remove(options) && mState == CONNECT_STATE_CONNECTED) {
+            try {
+                // NOTE: In order not to break the behavior of the support library, call
+                // removeSubscription instead of removeSubscriptionWithOptions when the options
+                // are null.
+                if (options == null) {
+                    mServiceBinder.removeSubscription(parentId, mServiceCallbacks);
+                } else {
+                    mServiceBinder.removeSubscriptionWithOptions(
+                            parentId, options, mServiceCallbacks);
+                }
+            } catch (RemoteException ex) {
+                // Process is crashing. We will disconnect, and upon reconnect we will
+                // automatically reregister. So nothing to do here.
+                Log.d(TAG, "removeSubscription failed with RemoteException parentId=" + parentId);
+            }
+        }
+        if (sub != null && sub.isEmpty()) {
+            mSubscriptions.remove(parentId);
+        }
+    }
+
     /**
      * For debugging.
      */
@@ -467,13 +567,26 @@
 
                 // we may receive some subscriptions before we are connected, so re-subscribe
                 // everything now
-                for (String id : mSubscriptions.keySet()) {
-                    try {
-                        mServiceBinder.addSubscription(id, mServiceCallbacks);
-                    } catch (RemoteException ex) {
-                        // Process is crashing.  We will disconnect, and upon reconnect we will
-                        // automatically reregister. So nothing to do here.
-                        Log.d(TAG, "addSubscription failed with RemoteException parentId=" + id);
+                for (Entry<String, Subscription> subscriptionEntry : mSubscriptions.entrySet()) {
+                    String id = subscriptionEntry.getKey();
+                    Subscription sub = subscriptionEntry.getValue();
+                    for (Bundle options : sub.getOptionsList()) {
+                        try {
+                            // NOTE: In order not to break the behavior of the support library,
+                            // call addSubscription instead of addSubscriptionWithOptions when
+                            // the options are null.
+                            if (options == null) {
+                                mServiceBinder.addSubscription(id, mServiceCallbacks);
+                            } else {
+                                mServiceBinder.addSubscriptionWithOptions(
+                                        id, options, mServiceCallbacks);
+                            }
+                        } catch (RemoteException ex) {
+                            // Process is crashing. We will disconnect, and upon reconnect we will
+                            // automatically reregister. So nothing to do here.
+                            Log.d(TAG, "addSubscription failed with RemoteException parentId="
+                                    + id);
+                        }
                     }
                 }
             }
@@ -508,7 +621,7 @@
     }
 
     private final void onLoadChildren(final IMediaBrowserServiceCallbacks callback,
-            final String parentId, final ParceledListSlice list) {
+            final String parentId, final ParceledListSlice list, final Bundle options) {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -525,16 +638,21 @@
 
                 // Check that the subscription is still subscribed.
                 final Subscription subscription = mSubscriptions.get(parentId);
-                if (subscription == null) {
-                    if (DBG) {
-                        Log.d(TAG, "onLoadChildren for id that isn't subscribed id="
-                                + parentId);
+                if (subscription != null) {
+                    // Tell the app.
+                    SubscriptionCallback subscriptionCallback = subscription.getCallback(options);
+                    if (subscriptionCallback != null) {
+                        if (options == null) {
+                            subscriptionCallback.onChildrenLoaded(parentId, data);
+                        } else {
+                            subscriptionCallback.onChildrenLoaded(parentId, data, options);
+                        }
+                        return;
                     }
-                    return;
                 }
-
-                // Tell the app.
-                subscription.callback.onChildrenLoaded(parentId, data);
+                if (DBG) {
+                    Log.d(TAG, "onLoadChildren for id that isn't subscribed id=" + parentId);
+                }
             }
         });
     }
@@ -697,7 +815,6 @@
         }
     }
 
-
     /**
      * Callbacks for connection related events.
      */
@@ -735,6 +852,19 @@
         }
 
         /**
+         * Called when the list of children is loaded or updated.
+         *
+         * @param parentId The media id of the parent media item.
+         * @param children The children which were loaded, or null if the id is invalid.
+         * @param options A bundle of service-specific arguments to send to the media
+         *            browse service. The contents of this bundle may affect the
+         *            information returned when browsing.
+         */
+        public void onChildrenLoaded(@NonNull String parentId, List<MediaItem> children,
+                @NonNull Bundle options) {
+        }
+
+        /**
          * Called when the id doesn't exist or other errors in subscribing.
          * <p>
          * If this is called, the subscription remains until {@link MediaBrowser#unsubscribe}
@@ -742,10 +872,25 @@
          * </p>
          *
          * @param parentId The media id of the parent media item whose children could
-         * not be loaded.
+         *            not be loaded.
          */
         public void onError(@NonNull String parentId) {
         }
+
+        /**
+         * Called when the id doesn't exist or other errors in subscribing.
+         * <p>
+         * If this is called, the subscription remains until {@link MediaBrowser#unsubscribe}
+         * called, because some errors may heal themselves.
+         * </p>
+         *
+         * @param parentId The media id of the parent media item whose children could
+         *            not be loaded.
+         * @param options A bundle of service-specific arguments sent to the media
+         *            browse service.
+         */
+        public void onError(@NonNull String parentId, @NonNull Bundle options) {
+        }
     }
 
     /**
@@ -909,20 +1054,65 @@
         }
 
         @Override
-        public void onLoadChildren(final String parentId, final ParceledListSlice list) {
+        public void onLoadChildren(final String parentId, final ParceledListSlice list,
+                final Bundle options) {
             MediaBrowser mediaBrowser = mMediaBrowser.get();
             if (mediaBrowser != null) {
-                mediaBrowser.onLoadChildren(this, parentId, list);
+                mediaBrowser.onLoadChildren(this, parentId, list, options);
             }
         }
     }
 
     private static class Subscription {
-        final String id;
-        SubscriptionCallback callback;
+        private final List<SubscriptionCallback> mCallbacks;
+        private final List<Bundle> mOptionsList;
 
-        Subscription(String id) {
-            this.id = id;
+        public Subscription() {
+            mCallbacks = new ArrayList<>();
+            mOptionsList = new ArrayList<>();
+        }
+
+        public boolean isEmpty() {
+            return mCallbacks.isEmpty();
+        }
+
+        public List<Bundle> getOptionsList() {
+            return mOptionsList;
+        }
+
+        public List<SubscriptionCallback> getCallbacks() {
+            return mCallbacks;
+        }
+
+        public void add(SubscriptionCallback callback, Bundle options) {
+            for (int i = 0; i < mOptionsList.size(); ++i) {
+                if (MediaBrowserUtils.areSameOptions(mOptionsList.get(i), options)) {
+                    mCallbacks.set(i, callback);
+                    return;
+                }
+            }
+            mCallbacks.add(callback);
+            mOptionsList.add(options);
+        }
+
+        public boolean remove(Bundle options) {
+            for (int i = 0; i < mOptionsList.size(); ++i) {
+                if (MediaBrowserUtils.areSameOptions(mOptionsList.get(i), options)) {
+                    mCallbacks.remove(i);
+                    mOptionsList.remove(i);
+                    return true;
+                }
+            }
+            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/browse/MediaBrowserUtils.java b/media/java/android/media/browse/MediaBrowserUtils.java
new file mode 100644
index 0000000..4f198ac
--- /dev/null
+++ b/media/java/android/media/browse/MediaBrowserUtils.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.media.browse;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+public class MediaBrowserUtils {
+    public static boolean areSameOptions(Bundle options1, Bundle options2) {
+        if (options1 == options2) {
+            return true;
+        } else if (options1 == null) {
+            return options2.getInt(MediaBrowser.EXTRA_PAGE, -1) == -1
+                    && options2.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1) == -1;
+        } else if (options2 == null) {
+            return options1.getInt(MediaBrowser.EXTRA_PAGE, -1) == -1
+                    && options1.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1) == -1;
+        } else {
+            return options1.getInt(MediaBrowser.EXTRA_PAGE, -1)
+                    == options2.getInt(MediaBrowser.EXTRA_PAGE, -1)
+                    && options1.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1)
+                    == options2.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1);
+        }
+    }
+
+    public static boolean hasDuplicatedItems(Bundle options1, Bundle options2) {
+        int page1 = options1.getInt(MediaBrowser.EXTRA_PAGE, -1);
+        int page2 = options2.getInt(MediaBrowser.EXTRA_PAGE, -1);
+        int pageSize1 = options1.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1);
+        int pageSize2 = options2.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1);
+
+        int startIndex1, startIndex2, endIndex1, endIndex2;
+        if (page1 == -1 || pageSize1 == -1) {
+            startIndex1 = 0;
+            endIndex1 = Integer.MAX_VALUE;
+        } else {
+            startIndex1 = pageSize1 * (page1 - 1);
+            endIndex1 = startIndex1 + pageSize1 - 1;
+        }
+
+        if (page2 == -1 || pageSize2 == -1) {
+            startIndex2 = 0;
+            endIndex2 = Integer.MAX_VALUE;
+        } else {
+            startIndex2 = pageSize2 * (page2 - 1);
+            endIndex2 = startIndex2 + pageSize2 - 1;
+        }
+
+        if (startIndex1 <= startIndex2 && startIndex2 <= endIndex1) {
+            return true;
+        } else if (startIndex1 <= endIndex2 && endIndex2 <= endIndex1) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
new file mode 100644
index 0000000..ebba343
--- /dev/null
+++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
@@ -0,0 +1,180 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.soundtrigger;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.os.Handler;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.app.ISoundTriggerService;
+
+import java.io.PrintWriter;
+import java.util.UUID;
+
+/**
+ * A class that allows interaction with the actual sound trigger detection on the system.
+ * Sound trigger detection refers to a detectors that match generic sound patterns that are
+ * not voice-based. The voice-based recognition models should utilize the {@link
+ * VoiceInteractionService} instead. Access to this class is protected by a permission
+ * granted only to system or privileged apps.
+ *
+ * @hide
+ */
+public final class SoundTriggerDetector {
+    private static final boolean DBG = false;
+    private static final String TAG = "SoundTriggerDetector";
+
+    private final Object mLock = new Object();
+
+    private final ISoundTriggerService mSoundTriggerService;
+    private final UUID mSoundModelId;
+    private final Callback mCallback;
+    private final Handler mHandler;
+    private final RecognitionCallback mRecognitionCallback;
+
+    public abstract class Callback {
+        /**
+         * Called when the availability of the sound model changes.
+         */
+        public abstract void onAvailabilityChanged(int status);
+
+        /**
+         * Called when the sound model has triggered (such as when it matched a
+         * given sound pattern).
+         */
+        public abstract void onDetected();
+
+        /**
+         *  Called when the detection fails due to an error.
+         */
+        public abstract void onError();
+
+        /**
+         * Called when the recognition is paused temporarily for some reason.
+         * This is an informational callback, and the clients shouldn't be doing anything here
+         * except showing an indication on their UI if they have to.
+         */
+        public abstract void onRecognitionPaused();
+
+        /**
+         * Called when the recognition is resumed after it was temporarily paused.
+         * This is an informational callback, and the clients shouldn't be doing anything here
+         * except showing an indication on their UI if they have to.
+         */
+        public abstract void onRecognitionResumed();
+    }
+
+    /**
+     * This class should be constructed by the {@link SoundTriggerManager}.
+     * @hide
+     */
+    SoundTriggerDetector(ISoundTriggerService soundTriggerService, UUID soundModelId,
+            @NonNull Callback callback, @Nullable Handler handler) {
+        mSoundTriggerService = soundTriggerService;
+        mSoundModelId = soundModelId;
+        mCallback = callback;
+        if (handler == null) {
+            mHandler = new Handler();
+        } else {
+            mHandler = handler;
+        }
+        mRecognitionCallback = new RecognitionCallback();
+    }
+
+    /**
+     * Starts recognition on the associated sound model. Result is indicated via the
+     * {@link Callback}.
+     * @return Indicates whether the call succeeded or not.
+     */
+    public boolean startRecognition() {
+        if (DBG) {
+            Slog.d(TAG, "startRecognition()");
+        }
+        try {
+            mSoundTriggerService.startRecognition(new ParcelUuid(mSoundModelId),
+                    mRecognitionCallback);
+        } catch (RemoteException e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Stops recognition for the associated model.
+     */
+    public boolean stopRecognition() {
+        try {
+            mSoundTriggerService.stopRecognition(new ParcelUuid(mSoundModelId),
+                    mRecognitionCallback);
+        } catch (RemoteException e) {
+            return false;
+        }
+        return true;
+    }
+
+    public void dump(String prefix, PrintWriter pw) {
+        synchronized (mLock) {
+            // TODO: Dump useful debug information.
+        }
+    }
+
+    /**
+     * Callback that handles events from the lower sound trigger layer.
+     * @hide
+     */
+    private static class RecognitionCallback extends
+            IRecognitionStatusCallback.Stub {
+
+        /**
+         * @hide
+         */
+        @Override
+        public void onDetected(SoundTrigger.RecognitionEvent event) {
+            Slog.e(TAG, "onDetected()" + event);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void onError(int status) {
+            Slog.e(TAG, "onError()" + status);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void onRecognitionPaused() {
+            Slog.e(TAG, "onRecognitionPaused()");
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void onRecognitionResumed() {
+            Slog.e(TAG, "onRecognitionResumed()");
+        }
+    }
+}
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
new file mode 100644
index 0000000..4ae8e72
--- /dev/null
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java
@@ -0,0 +1,172 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.soundtrigger;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.os.Handler;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.app.ISoundTriggerService;
+
+import java.util.HashMap;
+import java.util.UUID;
+
+/**
+ * This class provides management of non-voice (general sound trigger) based sound recognition
+ * models. Usage of this class is restricted to system or signature applications only. This allows
+ * OEMs to write apps that can manage non-voice based sound trigger models.
+ *
+ * @hide
+ * TODO: Mark this as a SystemApi and get approval.
+ */
+public final class SoundTriggerManager {
+    private static final boolean DBG = false;
+    private static final String TAG = "SoundTriggerManager";
+
+    private final Context mContext;
+    private final ISoundTriggerService mSoundTriggerService;
+
+    // Stores a mapping from the sound model UUID to the SoundTriggerInstance created by
+    // the createSoundTriggerDetector() call.
+    private final HashMap<UUID, SoundTriggerDetector> mReceiverInstanceMap;
+
+    /**
+     * @hide
+     */
+    public SoundTriggerManager(Context context, ISoundTriggerService soundTriggerService ) {
+        if (DBG) {
+            Slog.i(TAG, "SoundTriggerManager created.");
+        }
+        mSoundTriggerService = soundTriggerService;
+        mContext = context;
+        mReceiverInstanceMap = new HashMap<UUID, SoundTriggerDetector>();
+    }
+
+    /**
+     * Updates the given sound trigger model.
+     */
+    public void updateModel(Model model) {
+        try {
+            mSoundTriggerService.updateSoundModel(model.getGenericSoundModel());
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Returns the sound trigger model represented by the given UUID. An instance of {@link Model}
+     * is returned.
+     */
+    public Model getModel(UUID soundModelId) {
+        try {
+            return new Model(mSoundTriggerService.getSoundModel(
+                    new ParcelUuid(soundModelId)));
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Deletes the sound model represented by the provided UUID.
+     */
+    public void deleteModel(UUID soundModelId) {
+        try {
+            mSoundTriggerService.deleteSoundModel(new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Creates an instance of {@link SoundTriggerDetector} which can be used to start/stop
+     * recognition on the model and register for triggers from the model. Note that this call
+     * invalidates any previously returned instances for the same sound model Uuid.
+     *
+     * @param soundModelId UUID of the sound model to create the receiver object for.
+     * @param callback Instance of the {@link SoundTriggerDetector#Callback} object for the
+     * callbacks for the given sound model.
+     * @param handler The Handler to use for the callback operations. A null value will use the
+     * current thread's Looper.
+     * @return Instance of {@link SoundTriggerDetector} or null on error.
+     */
+    @Nullable
+    public SoundTriggerDetector createSoundTriggerDetector(UUID soundModelId,
+            @NonNull SoundTriggerDetector.Callback callback, @Nullable Handler handler) {
+        if (soundModelId == null) {
+            return null;
+        }
+
+        SoundTriggerDetector oldInstance = mReceiverInstanceMap.get(soundModelId);
+        if (oldInstance != null) {
+            // Shutdown old instance.
+        }
+        SoundTriggerDetector newInstance = new SoundTriggerDetector(mSoundTriggerService,
+                soundModelId, callback, handler);
+        mReceiverInstanceMap.put(soundModelId, newInstance);
+        return newInstance;
+    }
+
+    /**
+     * Class captures the data and fields that represent a non-keyphrase sound model. Use the
+     * factory constructor {@link Model#create()} to create an instance.
+     */
+    // We use encapsulation to expose the SoundTrigger.GenericSoundModel as a SystemApi. This
+    // prevents us from exposing SoundTrigger.GenericSoundModel as an Api.
+    public static class Model {
+
+        private SoundTrigger.GenericSoundModel mGenericSoundModel;
+
+        /**
+         * @hide
+         */
+        Model(SoundTrigger.GenericSoundModel soundTriggerModel) {
+            mGenericSoundModel = soundTriggerModel;
+        }
+
+        /**
+         * Factory constructor to create a SoundModel instance for use with methods in this
+         * class.
+         */
+        public static Model create(UUID modelUuid, UUID vendorUuid, byte[] data) {
+            return new Model(new SoundTrigger.GenericSoundModel(modelUuid,
+                        vendorUuid, data));
+        }
+
+        public UUID getModelUuid() {
+            return mGenericSoundModel.uuid;
+        }
+
+        public UUID getVendorUuid() {
+            return mGenericSoundModel.vendorUuid;
+        }
+
+        public byte[] getModelData() {
+            return mGenericSoundModel.data;
+        }
+
+        /**
+         * @hide
+         */
+        SoundTrigger.GenericSoundModel getGenericSoundModel() {
+            return mGenericSoundModel;
+        }
+    }
+}
diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl
index 86c0e5d..8ef5ca0 100644
--- a/media/java/android/media/tv/ITvInputClient.aidl
+++ b/media/java/android/media/tv/ITvInputClient.aidl
@@ -43,4 +43,10 @@
     void onTimeShiftStatusChanged(int status, int seq);
     void onTimeShiftStartPositionChanged(long timeMs, int seq);
     void onTimeShiftCurrentPositionChanged(long timeMs, int seq);
+
+    // For the recording session
+    void onConnected(int seq);
+    void onRecordingStarted(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 f8057db..0febc16 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -55,7 +55,8 @@
     void addBlockedRating(in String rating, int userId);
     void removeBlockedRating(in String rating, int userId);
 
-    void createSession(in ITvInputClient client, in String inputId, int seq, int userId);
+    void createSession(in ITvInputClient client, in String inputId, boolean isRecordingSession,
+            int seq, int userId);
     void releaseSession(in IBinder sessionToken, int userId);
 
     void setMainSession(in IBinder sessionToken, int userId);
@@ -77,12 +78,18 @@
 
     void unblockContent(in IBinder sessionToken, in String unblockedRating, int userId);
 
+    void timeShiftPlay(in IBinder sessionToken, in Uri recordedProgramUri, int userId);
     void timeShiftPause(in IBinder sessionToken, int userId);
     void timeShiftResume(in IBinder sessionToken, int userId);
     void timeShiftSeekTo(in IBinder sessionToken, long timeMs, int userId);
     void timeShiftSetPlaybackParams(in IBinder sessionToken, in PlaybackParams params, int userId);
     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 stopRecording(in IBinder sessionToken, int userId);
+
     // For TV input hardware binding
     List<TvInputHardwareInfo> getHardwareList();
     ITvInputHardware acquireTvInputHardware(int deviceId, in ITvInputHardwareCallback callback,
diff --git a/media/java/android/media/tv/ITvInputManagerCallback.aidl b/media/java/android/media/tv/ITvInputManagerCallback.aidl
index 6792680..3bf415b 100644
--- a/media/java/android/media/tv/ITvInputManagerCallback.aidl
+++ b/media/java/android/media/tv/ITvInputManagerCallback.aidl
@@ -16,13 +16,18 @@
 
 package android.media.tv;
 
+import android.media.tv.TvInputInfo;
+
 /**
  * Interface to receive callbacks from ITvInputManager regardless of sessions.
  * @hide
  */
 oneway interface ITvInputManagerCallback {
-    void onInputStateChanged(in String inputId, int state);
     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 String inputId, in TvInputInfo TvInputInfo);
 }
diff --git a/media/java/android/media/tv/ITvInputService.aidl b/media/java/android/media/tv/ITvInputService.aidl
index 7a853d1..bd05184 100644
--- a/media/java/android/media/tv/ITvInputService.aidl
+++ b/media/java/android/media/tv/ITvInputService.aidl
@@ -27,10 +27,11 @@
  * @hide
  */
 oneway interface ITvInputService {
-    void registerCallback(ITvInputServiceCallback callback);
+    void registerCallback(in ITvInputServiceCallback callback);
     void unregisterCallback(in ITvInputServiceCallback callback);
-    void createSession(in InputChannel channel, ITvInputSessionCallback callback,
+    void createSession(in InputChannel channel, in ITvInputSessionCallback callback,
             in String inputId);
+    void createRecordingSession(in ITvInputSessionCallback callback, in String inputId);
 
     // For hardware TvInputService
     void notifyHardwareAdded(in TvInputHardwareInfo hardwareInfo);
diff --git a/media/java/android/media/tv/ITvInputServiceCallback.aidl b/media/java/android/media/tv/ITvInputServiceCallback.aidl
index 74ab562..9f13882 100644
--- a/media/java/android/media/tv/ITvInputServiceCallback.aidl
+++ b/media/java/android/media/tv/ITvInputServiceCallback.aidl
@@ -27,4 +27,6 @@
     void addHardwareTvInput(in int deviceId, in TvInputInfo inputInfo);
     void addHdmiTvInput(in int id, in TvInputInfo inputInfo);
     void removeTvInput(in String inputId);
+
+    void setTvInputInfo(in String inputId, in TvInputInfo inputInfo);
 }
diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
index 6a06b8f..408a762 100644
--- a/media/java/android/media/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -48,9 +48,16 @@
 
     void unblockContent(in String unblockedRating);
 
+    void timeShiftPlay(in Uri recordedProgramUri);
     void timeShiftPause();
     void timeShiftResume();
     void timeShiftSeekTo(long timeMs);
     void timeShiftSetPlaybackParams(in PlaybackParams params);
     void timeShiftEnablePositionTracking(boolean enable);
+
+    // For the recording session
+    void connect(in Uri channelUri, in Bundle params);
+    void disconnect();
+    void startRecording();
+    void stopRecording();
 }
diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl
index e936810..cb6a05e 100644
--- a/media/java/android/media/tv/ITvInputSessionCallback.aidl
+++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl
@@ -40,4 +40,10 @@
     void onTimeShiftStatusChanged(int status);
     void onTimeShiftStartPositionChanged(long timeMs);
     void onTimeShiftCurrentPositionChanged(long timeMs);
+
+    // For the recording session
+    void onConnected();
+    void onRecordingStarted();
+    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 f8c6f3f..4ac5876 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -59,20 +59,29 @@
     private static final int DO_RELAYOUT_OVERLAY_VIEW = 11;
     private static final int DO_REMOVE_OVERLAY_VIEW = 12;
     private static final int DO_UNBLOCK_CONTENT = 13;
-    private static final int DO_TIME_SHIFT_PAUSE = 14;
-    private static final int DO_TIME_SHIFT_RESUME = 15;
-    private static final int DO_TIME_SHIFT_SEEK_TO = 16;
-    private static final int DO_TIME_SHIFT_SET_PLAYBACK_PARAMS = 17;
-    private static final int DO_TIME_SHIFT_ENABLE_POSITION_TRACKING = 18;
+    private static final int DO_TIME_SHIFT_PLAY = 14;
+    private static final int DO_TIME_SHIFT_PAUSE = 15;
+    private static final int DO_TIME_SHIFT_RESUME = 16;
+    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 final boolean mIsRecordingSession;
     private final HandlerCaller mCaller;
 
     private TvInputService.Session mTvInputSessionImpl;
+    private TvInputService.RecordingSession mTvInputRecordingSessionImpl;
+
     private InputChannel mChannel;
     private TvInputEventReceiver mReceiver;
 
     public ITvInputSessionWrapper(Context context, TvInputService.Session sessionImpl,
             InputChannel channel) {
+        mIsRecordingSession = false;
         mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
         mTvInputSessionImpl = sessionImpl;
         mChannel = channel;
@@ -81,9 +90,19 @@
         }
     }
 
+    public ITvInputSessionWrapper(Context context,
+            TvInputService.RecordingSession recordingSessionImpl) {
+        mIsRecordingSession = true;
+        mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
+        mTvInputRecordingSessionImpl = recordingSessionImpl;
+    }
+
     @Override
     public void executeMessage(Message msg) {
-        if (mTvInputSessionImpl == null) {
+        if (!mIsRecordingSession && mTvInputSessionImpl == null) {
+            return;
+        }
+        if (mIsRecordingSession && mTvInputRecordingSessionImpl == null) {
             return;
         }
 
@@ -138,7 +157,12 @@
             }
             case DO_APP_PRIVATE_COMMAND: {
                 SomeArgs args = (SomeArgs) msg.obj;
-                mTvInputSessionImpl.appPrivateCommand((String) args.arg1, (Bundle) args.arg2);
+                if (mIsRecordingSession) {
+                    mTvInputRecordingSessionImpl.appPrivateCommand(
+                            (String) args.arg1, (Bundle) args.arg2);
+                } else {
+                    mTvInputSessionImpl.appPrivateCommand((String) args.arg1, (Bundle) args.arg2);
+                }
                 args.recycle();
                 break;
             }
@@ -160,6 +184,10 @@
                 mTvInputSessionImpl.unblockContent((String) msg.obj);
                 break;
             }
+            case DO_TIME_SHIFT_PLAY: {
+                mTvInputSessionImpl.timeShiftPlay((Uri) msg.obj);
+                break;
+            }
             case DO_TIME_SHIFT_PAUSE: {
                 mTvInputSessionImpl.timeShiftPause();
                 break;
@@ -180,6 +208,25 @@
                 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();
+                break;
+            }
+            case DO_STOP_RECORDING: {
+                mTvInputRecordingSessionImpl.stopRecording();
+                break;
+            }
             default: {
                 Log.w(TAG, "Unhandled message code: " + msg.what);
                 break;
@@ -274,6 +321,12 @@
     }
 
     @Override
+    public void timeShiftPlay(Uri recordedProgramUri) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(
+                DO_TIME_SHIFT_PLAY, recordedProgramUri));
+    }
+
+    @Override
     public void timeShiftPause() {
         mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_TIME_SHIFT_PAUSE));
     }
@@ -300,6 +353,28 @@
                 DO_TIME_SHIFT_ENABLE_POSITION_TRACKING, enable));
     }
 
+    @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));
+    }
+
+    @Override
+    public void stopRecording() {
+        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_STOP_RECORDING));
+    }
+
     private final class TvInputEventReceiver extends InputEventReceiver {
         public TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
             super(inputChannel, looper);
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 7cd086e..62a01dc 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -54,6 +54,7 @@
 
     private static final String PATH_CHANNEL = "channel";
     private static final String PATH_PROGRAM = "program";
+    private static final String PATH_RECORDED_PROGRAM = "recorded_program";
     private static final String PATH_PASSTHROUGH = "passthrough";
 
     /**
@@ -273,6 +274,15 @@
     }
 
     /**
+     * Builds a URI that points to a specific recorded program.
+     *
+     * @param recordedProgramId The ID of the recorded program to point to.
+     */
+    public static final Uri buildRecordedProgramUri(long recordedProgramId) {
+        return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, recordedProgramId);
+    }
+
+    /**
      * Builds a URI that points to a specific program the user watched.
      *
      * @param watchedProgramId The ID of the watched program to point to.
@@ -941,6 +951,8 @@
          *
          * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
          *
+         * <p>This is a required field.
+         *
          * <p>Type: INTEGER (long)
          */
         public static final String COLUMN_CHANNEL_ID = "channel_id";
@@ -1336,6 +1348,382 @@
     }
 
     /**
+     * Column definitions for the recorded TV programs table.
+     *
+     * <p>By default, the query results will be sorted by {@link #COLUMN_START_TIME_UTC_MILLIS} in
+     * ascending order.
+     */
+    public static final class RecordedPrograms implements BaseTvColumns {
+
+        /** The content:// style URI for this table. */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_RECORDED_PROGRAM);
+
+        /** The MIME type of a directory of recorded TV programs. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
+
+        /** The MIME type of a single recorded TV program. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
+
+        /**
+         * 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}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
+         * @see Programs#COLUMN_CHANNEL_ID
+         */
+        public static final String COLUMN_CHANNEL_ID = Programs.COLUMN_CHANNEL_ID;
+
+        /**
+         * The title of this recorded TV program.
+         *
+         * <p>If this recorded program is an episodic TV show, it is recommended that the title is
+         * the series title and its related fields ({@link #COLUMN_SEASON_NUMBER},
+         * {@link #COLUMN_EPISODE_NUMBER}, and {@link #COLUMN_EPISODE_TITLE}) are filled in.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_TITLE
+         */
+        public static final String COLUMN_TITLE = Programs.COLUMN_TITLE;
+
+        /**
+         * The season number of this recorded TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_SEASON_NUMBER
+         */
+        public static final String COLUMN_SEASON_NUMBER = Programs.COLUMN_SEASON_NUMBER;
+
+        /**
+         * The episode number of this recorded TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_EPISODE_NUMBER
+         */
+        public static final String COLUMN_EPISODE_NUMBER = Programs.COLUMN_EPISODE_NUMBER;
+
+        /**
+         * The episode title of this recorded TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_EPISODE_TITLE
+         */
+        public static final String COLUMN_EPISODE_TITLE = Programs.COLUMN_EPISODE_TITLE;
+
+        /**
+         * The start time of the original TV program, in milliseconds since the epoch.
+         *
+         * <p>Type: INTEGER (long)
+         * @see Programs#COLUMN_START_TIME_UTC_MILLIS
+         */
+        public static final String COLUMN_START_TIME_UTC_MILLIS =
+                Programs.COLUMN_START_TIME_UTC_MILLIS;
+
+        /**
+         * The end time of the original TV program, in milliseconds since the epoch.
+         *
+         * <p>Type: INTEGER (long)
+         * @see Programs#COLUMN_END_TIME_UTC_MILLIS
+         */
+        public static final String COLUMN_END_TIME_UTC_MILLIS = Programs.COLUMN_END_TIME_UTC_MILLIS;
+
+        /**
+         * The comma-separated genre string of this recorded TV program.
+         *
+         * <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.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_BROADCAST_GENRE
+         */
+        public static final String COLUMN_BROADCAST_GENRE = Programs.COLUMN_BROADCAST_GENRE;
+
+        /**
+         * The comma-separated canonical genre string of this recorded TV program.
+         *
+         * <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.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_CANONICAL_GENRE
+         * @see Programs.Genres
+         */
+        public static final String COLUMN_CANONICAL_GENRE = Programs.COLUMN_CANONICAL_GENRE;
+
+        /**
+         * The short description of this recorded TV program that is displayed to the user by
+         * default.
+         *
+         * <p>It is recommended to limit the length of the descriptions to 256 characters.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_SHORT_DESCRIPTION
+         */
+        public static final String COLUMN_SHORT_DESCRIPTION = Programs.COLUMN_SHORT_DESCRIPTION;
+
+        /**
+         * The detailed, lengthy description of this recorded TV program that is displayed only when
+         * the user wants to see more information.
+         *
+         * <p>TV input services should leave this field empty if they have no additional details
+         * beyond {@link #COLUMN_SHORT_DESCRIPTION}.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_LONG_DESCRIPTION
+         */
+        public static final String COLUMN_LONG_DESCRIPTION = Programs.COLUMN_LONG_DESCRIPTION;
+
+        /**
+         * The width of the video for this recorded TV program, in the unit of pixels.
+         *
+         * <p>Together with {@link #COLUMN_VIDEO_HEIGHT} this is used to determine the video
+         * resolution of the current recorded TV program. Can be empty if it is not known or the
+         * recorded program does not convey any video.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_VIDEO_WIDTH
+         */
+        public static final String COLUMN_VIDEO_WIDTH = Programs.COLUMN_VIDEO_WIDTH;
+
+        /**
+         * The height of the video for this recorded TV program, in the unit of pixels.
+         *
+         * <p>Together with {@link #COLUMN_VIDEO_WIDTH} this is used to determine the video
+         * resolution of the current recorded TV program. Can be empty if it is not known or the
+         * recorded program does not convey any video.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_VIDEO_HEIGHT
+         */
+        public static final String COLUMN_VIDEO_HEIGHT = Programs.COLUMN_VIDEO_HEIGHT;
+
+        /**
+         * The comma-separated audio languages of this recorded TV program.
+         *
+         * <p>This is used to describe available audio languages included in the recorded program.
+         * Use either ISO 639-1 or 639-2/T codes.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_AUDIO_LANGUAGE
+         */
+        public static final String COLUMN_AUDIO_LANGUAGE = Programs.COLUMN_AUDIO_LANGUAGE;
+
+        /**
+         * The comma-separated content ratings of this recorded TV program.
+         *
+         * <p>This is used to describe the content rating(s) of this recorded program. Each
+         * comma-separated content rating sub-string should be generated by calling
+         * {@link TvContentRating#flattenToString}. Note that in most cases the recorded program
+         * content is rated by a single rating system, thus resulting in a corresponding single
+         * sub-string that does not require comma separation and multiple sub-strings appear only
+         * when the recorded program content is rated by two or more content rating systems. If any
+         * of those ratings is specified as "blocked rating" in the user's parental control
+         * settings, the TV input service should block the current content and wait for the signal
+         * that it is okay to unblock.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_CONTENT_RATING
+         */
+        public static final String COLUMN_CONTENT_RATING = Programs.COLUMN_CONTENT_RATING;
+
+        /**
+         * The URI for the poster art of this recorded TV program.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_POSTER_ART_URI
+         */
+        public static final String COLUMN_POSTER_ART_URI = Programs.COLUMN_POSTER_ART_URI;
+
+        /**
+         * The URI for the thumbnail of this recorded TV program.
+         *
+         * <p>The system can generate a thumbnail from the poster art if this column is not
+         * specified. Thus it is not necessary for TV input services to include a thumbnail if it is
+         * just a scaled image of the poster art.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_THUMBNAIL_URI
+         */
+        public static final String COLUMN_THUMBNAIL_URI = Programs.COLUMN_THUMBNAIL_URI;
+
+        /**
+         * The flag indicating whether this recorded TV program is searchable or not.
+         *
+         * <p>The columns of searchable recorded programs can be read by other applications that
+         * have proper permission. Care must be taken not to open sensitive data.
+         *
+         * <p>A value of 1 indicates that the recorded program is searchable and its columns can be
+         * read by other applications, a value of 0 indicates that the recorded program is hidden
+         * and its columns can be read only by the package that owns the recorded program and the
+         * system. If not specified, this value is set to 1 (searchable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @see Programs#COLUMN_SEARCHABLE
+         */
+        public static final String COLUMN_SEARCHABLE = Programs.COLUMN_SEARCHABLE;
+
+        /**
+         * The URI of the recording data for this recorded program.
+         *
+         * <p>Together with {@link #COLUMN_RECORDING_DATA_BYTES}, applications can use this
+         * information to manage recording storage. The URI should indicate a file or directory with
+         * the scheme {@link android.content.ContentResolver#SCHEME_FILE}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_RECORDING_DATA_BYTES
+         */
+        public static final String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
+
+        /**
+         * The data size (in bytes) for this recorded program.
+         *
+         * <p>Together with {@link #COLUMN_RECORDING_DATA_URI}, applications can use this
+         * information to manage recording storage.
+         *
+         * <p>Type: INTEGER (long)
+         * @see #COLUMN_RECORDING_DATA_URI
+         */
+        public static final String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
+
+        /**
+         * The duration (in milliseconds) of this recorded program.
+         *
+         * <p>The actual duration of the recorded program can differ from the one calculated by
+         * {@link #COLUMN_END_TIME_UTC_MILLIS} - {@link #COLUMN_START_TIME_UTC_MILLIS} as program
+         * recording can be interrupted in the middle for some reason, resulting in a partially
+         * recorded program, which is still playable.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
+
+        /**
+         * The expiration time for this recorded program, in milliseconds since the epoch.
+         *
+         * <p>Recorded TV programs do not expire by default unless explicitly requested by the user
+         * or the user allows applications to delete them in order to free up disk space for future
+         * recording. However, some TV content can have expiration date set by the content provider
+         * when recorded. This field is used to indicate such a restriction.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS =
+                "recording_expire_time_utc_millis";
+
+
+        /**
+         * Internal data used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: BLOB
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_DATA
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_DATA =
+                Programs.COLUMN_INTERNAL_PROVIDER_DATA;
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG1
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 =
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG1;
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG2
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 =
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG2;
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG3
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 =
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG3;
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_INTERNAL_PROVIDER_FLAG4
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 =
+                Programs.COLUMN_INTERNAL_PROVIDER_FLAG4;
+
+        /**
+         * The version number of this row entry used by TV input services.
+         *
+         * <p>This is best used by sync adapters to identify the rows to update. The number can be
+         * defined by individual TV input services. One may assign the same value as
+         * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV
+         * broadcast.
+         *
+         * <p>Type: INTEGER
+         * @see Programs#COLUMN_VERSION_NUMBER
+         */
+        public static final String COLUMN_VERSION_NUMBER = Programs.COLUMN_VERSION_NUMBER;
+
+        private RecordedPrograms() {}
+    }
+
+    /**
      * Column definitions for the TV programs that the user watched. Applications do not have access
      * to this table.
      *
@@ -1376,6 +1764,8 @@
         /**
          * The ID of the TV channel that provides this TV program.
          *
+         * <p>This is a required field.
+         *
          * <p>Type: INTEGER (long)
          */
         public static final String COLUMN_CHANNEL_ID = "channel_id";
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index a3d748e..671a86f 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -120,6 +120,8 @@
     private final String mId;
     private final String mParentId;
     private final int mType;
+    private final int mTunerCount;
+    private final boolean mCanRecord;
     private final boolean mIsHardwareInput;
 
     // Attributes from XML meta data.
@@ -127,9 +129,11 @@
     private String mSettingsActivity;
 
     private HdmiDeviceInfo mHdmiDeviceInfo;
-    private int mLabelRes;
+    private int mLabelResId;
+    // TODO: Remove when createTvInputInfo() is removed.
     private String mLabel;
     private Icon mIcon;
+    // TODO: Remove when createTvInputInfo() is removed.
     private Uri mIconUri;
     private boolean mIsConnectedToHdmiSwitch;
 
@@ -149,20 +153,6 @@
     }
 
     /**
-     * Create a new instance of the TvInputInfo class,
-     * instantiating it from the given Context and ResolveInfo.
-     *
-     * @param service The ResolveInfo returned from the package manager about this TV input service.
-     * @hide
-     */
-    public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service)
-            throws XmlPullParserException, IOException {
-        return createTvInputInfo(context, service, generateInputIdForComponentName(
-                new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name)),
-                null, TYPE_TUNER, false, 0, null, null, null, false);
-    }
-
-    /**
      * Create a new instance of the TvInputInfo class, instantiating it from the given Context,
      * ResolveInfo, and HdmiDeviceInfo.
      *
@@ -175,18 +165,20 @@
      *            {@link android.content.ContentResolver#openInputStream}. If it is {@code null},
      *            the application icon of {@code service} will be loaded.
      * @hide
+     * @deprecated Use {@link Builder} instead.
      */
+    @Deprecated
     @SystemApi
     public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
             HdmiDeviceInfo hdmiDeviceInfo, String parentId, String label, Uri iconUri)
                     throws XmlPullParserException, IOException {
-        boolean isConnectedToHdmiSwitch = (hdmiDeviceInfo.getPhysicalAddress() & 0x0FFF) != 0;
-        TvInputInfo input = createTvInputInfo(context, service, generateInputIdForHdmiDevice(
-                new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name),
-                hdmiDeviceInfo), parentId, TYPE_HDMI, true, 0, label, null, iconUri,
-                isConnectedToHdmiSwitch);
-        input.mHdmiDeviceInfo = hdmiDeviceInfo;
-        return input;
+        TvInputInfo info = new TvInputInfo.Builder(context, service)
+                .setHdmiDeviceInfo(hdmiDeviceInfo)
+                .setParentId(parentId)
+                .build();
+        info.mLabel = label;
+        info.mIconUri = iconUri;
+        return info;
     }
 
     /**
@@ -201,18 +193,19 @@
      * @param icon The {@link android.graphics.drawable.Icon} to load the icon image. If it is
      *            {@code null}, the application icon of {@code service} will be loaded.
      * @hide
+     * @deprecated Use {@link Builder} instead.
      */
+    @Deprecated
     @SystemApi
     public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
             HdmiDeviceInfo hdmiDeviceInfo, String parentId, int labelRes, Icon icon)
             throws XmlPullParserException, IOException {
-        boolean isConnectedToHdmiSwitch = (hdmiDeviceInfo.getPhysicalAddress() & 0x0FFF) != 0;
-        TvInputInfo input = createTvInputInfo(context, service, generateInputIdForHdmiDevice(
-                new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name),
-                hdmiDeviceInfo), parentId, TYPE_HDMI, true, labelRes, null, icon, null,
-                isConnectedToHdmiSwitch);
-        input.mHdmiDeviceInfo = hdmiDeviceInfo;
-        return input;
+        return new TvInputInfo.Builder(context, service)
+                .setHdmiDeviceInfo(hdmiDeviceInfo)
+                .setParentId(parentId)
+                .setLabel(labelRes)
+                .setIcon(icon)
+                .build();
     }
 
     /**
@@ -227,15 +220,19 @@
      *            {@link android.content.ContentResolver#openInputStream}. If it is {@code null},
      *            the application icon of {@code service} will be loaded.
      * @hide
+     * @deprecated Use {@link Builder} instead.
      */
+    @Deprecated
     @SystemApi
     public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
             TvInputHardwareInfo hardwareInfo, String label, Uri iconUri)
                     throws XmlPullParserException, IOException {
-        int inputType = sHardwareTypeToTvInputType.get(hardwareInfo.getType(), TYPE_TUNER);
-        return createTvInputInfo(context, service, generateInputIdForHardware(
-                new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name),
-                hardwareInfo), null, inputType, true, 0, label, null, iconUri, false);
+        TvInputInfo info = new TvInputInfo.Builder(context, service)
+                .setTvInputHardwareInfo(hardwareInfo)
+                .build();
+        info.mLabel = label;
+        info.mIconUri = iconUri;
+        return info;
     }
 
     /**
@@ -249,21 +246,55 @@
      * @param icon The {@link android.graphics.drawable.Icon} to load the icon image. If it is
      *            {@code null}, the application icon of {@code service} will be loaded.
      * @hide
+     * @deprecated Use {@link Builder} instead.
      */
+    @Deprecated
     @SystemApi
     public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
             TvInputHardwareInfo hardwareInfo, int labelRes, Icon icon)
             throws XmlPullParserException, IOException {
-        int inputType = sHardwareTypeToTvInputType.get(hardwareInfo.getType(), TYPE_TUNER);
-        return createTvInputInfo(context, service, generateInputIdForHardware(
-                new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name),
-                hardwareInfo), null, inputType, true, labelRes, null, icon, null, false);
+        return new TvInputInfo.Builder(context, service)
+                .setTvInputHardwareInfo(hardwareInfo)
+                .setLabel(labelRes)
+                .setIcon(icon)
+                .build();
     }
 
-    private static TvInputInfo createTvInputInfo(Context context, ResolveInfo service, String id,
-            String parentId, int inputType, boolean isHardwareInput, int labelRes, String label,
-            Icon icon, Uri iconUri, boolean isConnectedToHdmiSwitch)
-                    throws XmlPullParserException, IOException {
+    static TvInputInfo createTvInputInfo(Context context, ResolveInfo resolveInfo, Icon icon,
+            int labelResId, int tunerCount, boolean canRecord, HdmiDeviceInfo hdmiDeviceInfo,
+            String parentId, TvInputHardwareInfo tvInputHardwareInfo)
+            throws IOException, XmlPullParserException {
+        ComponentName componentName = new ComponentName(resolveInfo.serviceInfo.packageName,
+                resolveInfo.serviceInfo.name);
+        String id;
+        int type;
+        boolean isHardwareInput = false;
+        boolean isConnectedToHdmiSwitch = false;
+
+        if (hdmiDeviceInfo != null) {
+            id = generateInputIdForHdmiDevice(componentName, hdmiDeviceInfo);
+            type = TYPE_HDMI;
+            isHardwareInput = true;
+            isConnectedToHdmiSwitch = (hdmiDeviceInfo.getPhysicalAddress() & 0x0FFF) != 0;
+            tunerCount = 0;
+        } else if (tvInputHardwareInfo != null) {
+            id = generateInputIdForHardware(componentName, tvInputHardwareInfo);
+            type = sHardwareTypeToTvInputType.get(tvInputHardwareInfo.getType(), TYPE_TUNER);
+            isHardwareInput = true;
+            tunerCount = 0;
+        } else {
+            id = generateInputIdForComponentName(componentName);
+            type = TYPE_TUNER;
+        }
+
+        TvInputInfo info = new TvInputInfo(resolveInfo, id, parentId, type, isHardwareInput,
+                isConnectedToHdmiSwitch, tunerCount, canRecord);
+        return parseServiceMetadata(context, resolveInfo, type, info);
+    }
+
+    private static TvInputInfo parseServiceMetadata(
+            Context context, ResolveInfo service, int inputType, TvInputInfo input)
+            throws XmlPullParserException, IOException {
         ServiceInfo si = service.serviceInfo;
         PackageManager pm = context.getPackageManager();
         XmlResourceParser parser = null;
@@ -278,7 +309,7 @@
             AttributeSet attrs = Xml.asAttributeSet(parser);
 
             int type;
-            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                     && type != XmlPullParser.START_TAG) {
             }
 
@@ -288,7 +319,6 @@
                         "Meta-data does not start with tv-input-service tag in " + si.name);
             }
 
-            TvInputInfo input = new TvInputInfo(service, id, parentId, inputType, isHardwareInput);
             TypedArray sa = res.obtainAttributes(attrs,
                     com.android.internal.R.styleable.TvInputService);
             input.mSetupActivity = sa.getString(
@@ -307,12 +337,6 @@
             }
             sa.recycle();
 
-            input.mLabelRes = labelRes;
-            input.mLabel = label;
-            input.mIcon = icon;
-            input.mIconUri = iconUri;
-            input.mIsConnectedToHdmiSwitch = isConnectedToHdmiSwitch;
-            return input;
         } catch (NameNotFoundException e) {
             throw new XmlPullParserException("Unable to create context for: " + si.packageName);
         } finally {
@@ -320,6 +344,7 @@
                 parser.close();
             }
         }
+        return input;
     }
 
     /**
@@ -330,15 +355,23 @@
      * @param parentId ID of this TV input's parent input. {@code null} if none exists.
      * @param type The type of this TV input service.
      * @param isHardwareInput {@code true} if this TV input represents a hardware device.
-     *         {@code false} otherwise.
+     *            {@code false} otherwise.
+     * @param isConnectedToHdmiSwitch Whether a CEC device for this TV input is connected to an HDMI
+     *            switch, i.e., the device isn't directly connected to a HDMI port.
+     * @param tunerCount The number of tuners this TV input has.
+     * @param canRecord Whether this TV input can record TV programs.
      */
     private TvInputInfo(ResolveInfo service, String id, String parentId, int type,
-            boolean isHardwareInput) {
+            boolean isHardwareInput, boolean isConnectedToHdmiSwitch, int tunerCount,
+            boolean canRecord) {
         mService = service;
         mId = id;
         mParentId = parentId;
         mType = type;
         mIsHardwareInput = isHardwareInput;
+        mIsConnectedToHdmiSwitch = isConnectedToHdmiSwitch;
+        mTunerCount = tunerCount;
+        mCanRecord = canRecord;
     }
 
     /**
@@ -419,6 +452,27 @@
     }
 
     /**
+     * Returns the number of tuners this TV input has.
+     *
+     * <p>This method is valid only for the input of type {@link #TYPE_TUNER}.
+     *
+     * <p>Tuners correspond to physical/logical resources that allow reception of TV signal. Having
+     * <i>N</i> tuners means that the TV input is capable of receiving <i>N</i> different channels
+     * concurrently.
+     *
+     */
+    public int getTunerCount() {
+        return mTunerCount;
+    }
+
+    /**
+     * Returns {@code true} if this TV input can record TV programs, {@code false} otherwise.
+     */
+    public boolean canRecord() {
+        return mCanRecord;
+    }
+
+    /**
      * Returns the HDMI device information of this TV input.
      * @hide
      */
@@ -481,9 +535,9 @@
      *         a label, its name is returned.
      */
     public CharSequence loadLabel(@NonNull Context context) {
-        if (mLabelRes != 0) {
-            return context.getPackageManager().getText(mService.serviceInfo.packageName, mLabelRes,
-                    null);
+        if (mLabelResId != 0) {
+            return context.getPackageManager().getText(mService.serviceInfo.packageName,
+                    mLabelResId, null);
         } else if (!TextUtils.isEmpty(mLabel)) {
             return mLabel;
         }
@@ -572,11 +626,13 @@
         dest.writeString(mSetupActivity);
         dest.writeString(mSettingsActivity);
         dest.writeInt(mType);
+        dest.writeInt(mTunerCount);
+        dest.writeByte(mCanRecord ? (byte) 1 : 0);
         dest.writeByte(mIsHardwareInput ? (byte) 1 : 0);
         dest.writeParcelable(mHdmiDeviceInfo, flags);
         dest.writeParcelable(mIcon, flags);
         dest.writeParcelable(mIconUri, flags);
-        dest.writeInt(mLabelRes);
+        dest.writeInt(mLabelResId);
         dest.writeString(mLabel);
         dest.writeByte(mIsConnectedToHdmiSwitch ? (byte) 1 : 0);
     }
@@ -649,16 +705,174 @@
         mSetupActivity = in.readString();
         mSettingsActivity = in.readString();
         mType = in.readInt();
+        mTunerCount = in.readInt();
+        mCanRecord = in.readByte() == 1;
         mIsHardwareInput = in.readByte() == 1;
         mHdmiDeviceInfo = in.readParcelable(null);
         mIcon = in.readParcelable(null);
         mIconUri = in.readParcelable(null);
-        mLabelRes = in.readInt();
+        mLabelResId = in.readInt();
         mLabel = in.readString();
         mIsConnectedToHdmiSwitch = in.readByte() == 1;
     }
 
     /**
+     * A convenience builder for creating {@link TvInputInfo} objects.
+     */
+    public static final class Builder {
+        private final Context mContext;
+        private final ResolveInfo mResolveInfo;
+        private Icon mIcon;
+        private int mLabelResId;
+        private int mTunerCount = 1;
+        private boolean mCanRecord;
+        private HdmiDeviceInfo mHdmiDeviceInfo;
+        private String mParentId;
+        private TvInputHardwareInfo mTvInputHardwareInfo;
+
+        /**
+         * Constructs a new builder for {@link TvInputInfo}.
+         *
+         * @param context A Context of the application package implementing this class.
+         * @param cls The component class that is to be used for the {@link TvInputService}.
+         */
+        public Builder(Context context, Class<?> cls) {
+            mContext = context;
+            Intent intent = new Intent(TvInputService.SERVICE_INTERFACE).setClass(context, cls);
+            mResolveInfo = context.getPackageManager().resolveService(intent,
+                    PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+        }
+
+        /**
+         * Constructs a new builder for {@link TvInputInfo}.
+         *
+         * @param resolveInfo The ResolveInfo returned from the package manager about this TV input
+         *            service.
+         * @hide
+         */
+        public Builder(Context context, ResolveInfo resolveInfo) {
+            if (context == null) {
+                throw new IllegalArgumentException("context cannot be null");
+            }
+            if (resolveInfo == null) {
+                throw new IllegalArgumentException("resolveInfo cannot be null");
+            }
+            mContext = context;
+            mResolveInfo = resolveInfo;
+        }
+
+        /**
+         * Sets the icon.
+         *
+         * @param icon The icon that represents this TV input.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setIcon(Icon icon) {
+            this.mIcon = icon;
+            return this;
+        }
+
+        /**
+         * Sets the label.
+         *
+         * @param resId The resource ID of the text to use.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setLabel(int resId) {
+            this.mLabelResId = resId;
+            return this;
+        }
+
+        /**
+         * Sets the HdmiDeviceInfo.
+         *
+         * @param hdmiDeviceInfo The HdmiDeviceInfo for a HDMI CEC logical device.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setHdmiDeviceInfo(HdmiDeviceInfo hdmiDeviceInfo) {
+            if (mTvInputHardwareInfo != null) {
+                Log.w(TAG, "TvInputHardwareInfo will not be used to build this TvInputInfo");
+                mTvInputHardwareInfo = null;
+            }
+            this.mHdmiDeviceInfo = hdmiDeviceInfo;
+            return this;
+        }
+
+        /**
+         * Sets the parent ID.
+         *
+         * @param parentId The parent ID.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setParentId(String parentId) {
+            this.mParentId = parentId;
+            return this;
+        }
+
+        /**
+         * Sets the TvInputHardwareInfo.
+         *
+         * @param tvInputHardwareInfo
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setTvInputHardwareInfo(TvInputHardwareInfo tvInputHardwareInfo) {
+            if (mHdmiDeviceInfo != null) {
+                Log.w(TAG, "mHdmiDeviceInfo will not be used to build this TvInputInfo");
+                mHdmiDeviceInfo = null;
+            }
+            this.mTvInputHardwareInfo = tvInputHardwareInfo;
+            return this;
+        }
+
+        /**
+         * Sets the tuner count. Valid only for {@link #TYPE_TUNER}.
+         *
+         * @param tunerCount The number of tuners this TV input has.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setTunerCount(int tunerCount) {
+            this.mTunerCount = tunerCount;
+            return this;
+        }
+
+        /**
+         * Sets whether this TV input can record TV programs or not.
+         *
+         * @param canRecord Whether this TV input can record TV programs.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setCanRecord(boolean canRecord) {
+            this.mCanRecord = canRecord;
+            return this;
+        }
+
+        /**
+         * Creates a {@link TvInputInfo} instance with the specified fields. Most of the information
+         * is obtained by parsing the AndroidManifest and {@link TvInputService#SERVICE_META_DATA}
+         * for the {@link TvInputService} this TV input implements.
+         *
+         * @return TvInputInfo containing information about this TV input.
+         * @throws IOException If there was an I/O error.
+         * @throws XmlPullParserException If there was an XML parsing error.
+         *
+         */
+        public TvInputInfo build() throws IOException, XmlPullParserException {
+            return createTvInputInfo(mContext, mResolveInfo, mIcon, mLabelResId, mTunerCount,
+                    mCanRecord, mHdmiDeviceInfo, mParentId, mTvInputHardwareInfo);
+        }
+    }
+
+    /**
      * Utility class for putting and getting settings for TV input.
      *
      * @hide
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 6a13f82..f1de8fd 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -16,6 +16,7 @@
 
 package android.media.tv;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -44,6 +45,8 @@
 
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -126,6 +129,35 @@
     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.
+     */
+    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.
+     */
+    public static final int RECORDING_ERROR_CONNECTION_FAILED = 1;
+
+    /**
+     * RecordingError when recording cannot proceed due to insufficient storage space.
+     */
+    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;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({RECORDING_ERROR_UNKNOWN, RECORDING_ERROR_CONNECTION_FAILED,
+            RECORDING_ERROR_INSUFFICIENT_SPACE, RECORDING_ERROR_RESOURCE_BUSY})
+    public @interface RecordingError {}
+
+    /**
      * The TV input is connected.
      *
      * <p>This state indicates that a source device is connected to the input port and is in the
@@ -416,6 +448,39 @@
          */
         public void onTimeShiftCurrentPositionChanged(Session session, long timeMs) {
         }
+
+        /**
+         * This is called when a recording session initiated by a call to {@link
+         * TvRecordingClient#connect(String, Uri)} has been established.
+         */
+        void onConnected(Session session) {
+        }
+
+        /**
+         * This is called when TV program recording on the current channel has started.
+         *
+         * @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
+         **/
+        void onRecordingStopped(Session session, Uri recordedProgramUri) {
+        }
+
+        /**
+         * This is called when an issue has occurred before or during recording.
+         *
+         * @param error The error code.
+         */
+        void onError(Session session, @TvInputManager.RecordingError int error) {
+        }
     }
 
     private static final class SessionCallbackRecord {
@@ -565,6 +630,46 @@
                 }
             });
         }
+
+        // For the recording session only
+        void postConnected() {
+            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);
+                }
+            });
+        }
+
+        // For the recording session only
+        void postRecordingStopped(final Uri recordedProgramUri) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onRecordingStopped(mSession, recordedProgramUri);
+                }
+            });
+        }
+
+        // For the recording session only
+        void postError(final int error) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onError(mSession, error);
+                }
+            });
+        }
     }
 
     /**
@@ -574,7 +679,7 @@
         /**
          * This is called when the state of a given TV input is changed.
          *
-         * @param inputId The id of the TV input.
+         * @param inputId The ID of the TV input.
          * @param state State of the TV input. The value is one of the following:
          * <ul>
          * <li>{@link TvInputManager#INPUT_STATE_CONNECTED}
@@ -591,7 +696,7 @@
          * <p>Normally it happens when the user installs a new TV input package that implements
          * {@link TvInputService} interface.
          *
-         * @param inputId The id of the TV input.
+         * @param inputId The ID of the TV input.
          */
         public void onInputAdded(String inputId) {
         }
@@ -602,7 +707,7 @@
          * <p>Normally it happens when the user uninstalls the previously installed TV input
          * package.
          *
-         * @param inputId The id of the TV input.
+         * @param inputId The ID of the TV input.
          */
         public void onInputRemoved(String inputId) {
         }
@@ -613,12 +718,21 @@
          * <p>Normally it happens when a previously installed TV input package is re-installed or
          * the media on which a newer version of the package exists becomes available/unavailable.
          *
-         * @param inputId The id of the TV input.
+         * @param inputId The ID of the TV input.
          * @hide
          */
         @SystemApi
         public void onInputUpdated(String inputId) {
         }
+
+        /**
+         * This is called when the information about a given TV input is changed.
+         *
+         * @param inputId The ID of the TV input.
+         * @param inputInfo TvInputInfo object that contains the information about the TV input.
+         */
+        public void onTvInputInfoChanged(String inputId, TvInputInfo inputInfo) {
+        }
     }
 
     private static final class TvInputCallbackRecord {
@@ -634,15 +748,6 @@
             return mCallback;
         }
 
-        public void postInputStateChanged(final String inputId, final int state) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mCallback.onInputStateChanged(inputId, state);
-                }
-            });
-        }
-
         public void postInputAdded(final String inputId) {
             mHandler.post(new Runnable() {
                 @Override
@@ -669,6 +774,24 @@
                 }
             });
         }
+
+        public void postInputStateChanged(final String inputId, final int state) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onInputStateChanged(inputId, state);
+                }
+            });
+        }
+
+        public void postTvInputInfoChanged(final String inputId, final TvInputInfo inputInfo) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onTvInputInfoChanged(inputId, inputInfo);
+                }
+            });
+        }
     }
 
     /**
@@ -876,19 +999,57 @@
                     record.postTimeShiftCurrentPositionChanged(timeMs);
                 }
             }
-        };
-        ITvInputManagerCallback managerCallback = new ITvInputManagerCallback.Stub() {
+
             @Override
-            public void onInputStateChanged(String inputId, int state) {
-                synchronized (mLock) {
-                    mStateMap.put(inputId, state);
-                    for (TvInputCallbackRecord record : mCallbackRecords) {
-                        record.postInputStateChanged(inputId, state);
+            public void onConnected(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();
+                }
+            }
+
+            @Override
+            public void onRecordingStopped(Uri recordedProgramUri, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postRecordingStopped(recordedProgramUri);
+                }
+            }
+
+            @Override
+            public void onError(int error, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postError(error);
+                }
+            }
+        };
+        ITvInputManagerCallback managerCallback = new ITvInputManagerCallback.Stub() {
+            @Override
             public void onInputAdded(String inputId) {
                 synchronized (mLock) {
                     mStateMap.put(inputId, INPUT_STATE_CONNECTED);
@@ -916,6 +1077,25 @@
                     }
                 }
             }
+
+            @Override
+            public void onInputStateChanged(String inputId, int state) {
+                synchronized (mLock) {
+                    mStateMap.put(inputId, state);
+                    for (TvInputCallbackRecord record : mCallbackRecords) {
+                        record.postInputStateChanged(inputId, state);
+                    }
+                }
+            }
+
+            @Override
+            public void onTvInputInfoChanged(String inputId, TvInputInfo inputInfo) {
+                synchronized (mLock) {
+                    for (TvInputCallbackRecord record : mCallbackRecords) {
+                        record.postTvInputInfoChanged(inputId, inputInfo);
+                    }
+                }
+            }
         };
         try {
             if (mService != null) {
@@ -972,7 +1152,7 @@
      * <li>{@link #INPUT_STATE_DISCONNECTED}
      * </ul>
      *
-     * @param inputId The id of the TV input.
+     * @param inputId The ID of the TV input.
      * @throws IllegalArgumentException if the argument is {@code null}.
      */
     public int getInputState(@NonNull String inputId) {
@@ -1139,7 +1319,7 @@
      * <p>The number of sessions that can be created at the same time is limited by the capability
      * of the given TV input.
      *
-     * @param inputId The id of the TV input.
+     * @param inputId The ID of the TV input.
      * @param callback A callback used to receive the created session.
      * @param handler A {@link Handler} that the session creation will be delivered to.
      * @hide
@@ -1147,6 +1327,28 @@
     @SystemApi
     public void createSession(@NonNull String inputId, @NonNull final SessionCallback callback,
             @NonNull Handler handler) {
+        createSessionInternal(inputId, false, callback, handler);
+    }
+
+    /**
+     * Creates a recording {@link Session} for a given TV input.
+     *
+     * <p>The number of sessions that can be created at the same time is limited by the capability
+     * of the given TV input.
+     *
+     * @param inputId The ID of the TV input.
+     * @param callback A callback used to receive the created session.
+     * @param handler A {@link Handler} that the session creation will be delivered to.
+     * @hide
+     */
+    @SystemApi
+    public void createRecordingSession(@NonNull String inputId,
+            @NonNull final SessionCallback callback, @NonNull Handler handler) {
+        createSessionInternal(inputId, true, callback, handler);
+    }
+
+    private void createSessionInternal(String inputId, boolean isRecordingSession,
+            SessionCallback callback, Handler handler) {
         Preconditions.checkNotNull(inputId);
         Preconditions.checkNotNull(callback);
         Preconditions.checkNotNull(handler);
@@ -1155,7 +1357,7 @@
             int seq = mNextSeq++;
             mSessionCallbackRecordMap.put(seq, record);
             try {
-                mService.createSession(mClient, inputId, seq, mUserId);
+                mService.createSession(mClient, inputId, isRecordingSession, seq, mUserId);
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -1171,7 +1373,7 @@
      * here. This method is designed to be used with {@link #captureFrame} in
      * capture scenarios specifically and not suitable for any other use.
      *
-     * @param inputId the id of the TV input.
+     * @param inputId The ID of the TV input.
      * @return List of {@link TvStreamConfig} which is available for capturing
      *   of the given TV input.
      * @hide
@@ -1188,7 +1390,7 @@
     /**
      * Take a snapshot of the given TV input into the provided Surface.
      *
-     * @param inputId the id of the TV input.
+     * @param inputId The ID of the TV input.
      * @param surface the {@link Surface} to which the snapshot is captured.
      * @param config the {@link TvStreamConfig} which is used for capturing.
      * @return true when the {@link Surface} is ready to be captured.
@@ -1607,7 +1809,7 @@
          * Returns the selected track for a given type. Returns {@code null} if the information is
          * not available or any of the tracks for the given type is not selected.
          *
-         * @return the ID of the selected track.
+         * @return The ID of the selected track.
          * @see #selectTrack
          */
         @Nullable
@@ -1697,6 +1899,21 @@
         }
 
         /**
+         * Plays a given recorded TV program.
+         */
+        void timeShiftPlay(Uri recordedProgramUri) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.timeShiftPlay(mToken, recordedProgramUri, mUserId);
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /**
          * Pauses the playback. Call {@link #timeShiftResume()} to restart the playback.
          */
         void timeShiftPause() {
@@ -1782,6 +1999,62 @@
         }
 
         /**
+         * Connects to a given channel for TV program recording.
+         */
+        void connect(Uri channelUri) {
+            connect(channelUri, null);
+        }
+
+        /**
+         * Tunes to a given channel.
+         *
+         * @param channelUri The URI of a channel.
+         * @param params Extra parameters.
+         */
+        void connect(@NonNull Uri channelUri, Bundle params) {
+            Preconditions.checkNotNull(channelUri);
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.connect(mToken, channelUri, params, 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.
+         */
+        void stopRecording() {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.stopRecording(mToken, mUserId);
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /**
          * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle)
          * TvInputService.Session.appPrivateCommand()} on the current TvView.
          *
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 053d43b6..f74ae66 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -16,6 +16,7 @@
 
 package android.media.tv;
 
+import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
@@ -136,6 +137,18 @@
             }
 
             @Override
+            public void createRecordingSession(ITvInputSessionCallback cb, String inputId) {
+                if (cb == null) {
+                    return;
+                }
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = cb;
+                args.arg2 = inputId;
+                mServiceHandler.obtainMessage(ServiceHandler.DO_CREATE_RECORDING_SESSION, args)
+                        .sendToTarget();
+            }
+
+            @Override
             public void notifyHardwareAdded(TvInputHardwareInfo hardwareInfo) {
                 mServiceHandler.obtainMessage(ServiceHandler.DO_ADD_HARDWARE_TV_INPUT,
                         hardwareInfo).sendToTarget();
@@ -174,6 +187,19 @@
     public abstract Session onCreateSession(String inputId);
 
     /**
+     * Returns a concrete implementation of {@link RecordingSession}.
+     *
+     * <p>May return {@code null} if this TV input service fails to create a recording session for
+     * some reason.
+     *
+     * @param inputId The ID of the TV input associated with the recording session.
+     */
+    @Nullable
+    public RecordingSession onCreateRecordingSession(String inputId) {
+        return null;
+    }
+
+    /**
      * Returns a new {@link TvInputInfo} object if this service is responsible for
      * {@code hardwareInfo}; otherwise, return {@code null}. Override to modify default behavior of
      * ignoring all hardware input.
@@ -229,6 +255,25 @@
         return null;
     }
 
+
+    /**
+     * Sets the TvInputInfo for this TV input.
+     *
+     * <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.
+     *
+     * @param inputId The ID of the TV input.
+     * @param inputInfo The TvInputInfo object that contains that new information.
+     */
+    public final void setTvInputInfo(String inputId, TvInputInfo inputInfo) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = inputId;
+        args.arg2 = inputInfo;
+        mServiceHandler.obtainMessage(ServiceHandler.DO_SET_TV_INPUT_INFO, args).sendToTarget();
+    }
+
     private boolean isPassthroughInput(String inputId) {
         if (mTvInputManager == null) {
             mTvInputManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
@@ -322,7 +367,7 @@
         @SystemApi
         public void notifySessionEvent(@NonNull final String eventType, final Bundle eventArgs) {
             Preconditions.checkNotNull(eventType);
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
                 @Override
                 public void run() {
                     try {
@@ -347,7 +392,8 @@
          * @param channelUri The URI of the new channel.
          */
         public void notifyChannelRetuned(final Uri channelUri) {
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -387,7 +433,8 @@
 
             // TODO: Validate the track list.
             final List<TvTrackInfo> tracksCopy = new ArrayList<>(tracks);
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -417,7 +464,8 @@
          * @see #onSelectTrack
          */
         public void notifyTrackSelected(final int type, final String trackId) {
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -443,7 +491,8 @@
          * @see #notifyVideoUnavailable
          */
         public void notifyVideoAvailable() {
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -478,7 +527,8 @@
                     || reason > TvInputManager.VIDEO_UNAVAILABLE_REASON_END) {
                 throw new IllegalArgumentException("Unknown reason: " + reason);
             }
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -518,7 +568,8 @@
          * @see TvInputManager
          */
         public void notifyContentAllowed() {
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -562,7 +613,8 @@
          */
         public void notifyContentBlocked(@NonNull final TvContentRating rating) {
             Preconditions.checkNotNull(rating);
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -603,7 +655,8 @@
          * </ul>
          */
         public void notifyTimeShiftStatusChanged(final int status) {
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -619,7 +672,8 @@
         }
 
         private void notifyTimeShiftStartPositionChanged(final long timeMs) {
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -635,7 +689,8 @@
         }
 
         private void notifyTimeShiftCurrentPositionChanged(final long timeMs) {
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -665,7 +720,8 @@
             if (left > right || top > bottom) {
                 throw new IllegalArgumentException("Invalid parameter");
             }
-            executeOrPostRunnable(new Runnable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
                 @Override
                 public void run() {
                     try {
@@ -858,13 +914,28 @@
         }
 
         /**
+         * Called when the application requests to play a given recorded TV program.
+         *
+         * @param recordedProgramUri The URI of a recorded TV program.
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
+         */
+        public void onTimeShiftPlay(Uri recordedProgramUri) {
+        }
+
+        /**
          * Called when the application requests to pause playback.
          *
-         * @see #onTimeShiftResume
-         * @see #onTimeShiftSeekTo
-         * @see #onTimeShiftSetPlaybackParams
-         * @see #onTimeShiftGetStartPosition
-         * @see #onTimeShiftGetCurrentPosition
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
          */
         public void onTimeShiftPause() {
         }
@@ -872,11 +943,12 @@
         /**
          * Called when the application requests to resume playback.
          *
-         * @see #onTimeShiftPause
-         * @see #onTimeShiftSeekTo
-         * @see #onTimeShiftSetPlaybackParams
-         * @see #onTimeShiftGetStartPosition
-         * @see #onTimeShiftGetCurrentPosition
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
          */
         public void onTimeShiftResume() {
         }
@@ -888,11 +960,12 @@
          * not in the range.
          *
          * @param timeMs The time position to seek to, in milliseconds since the epoch.
-         * @see #onTimeShiftResume
-         * @see #onTimeShiftPause
-         * @see #onTimeShiftSetPlaybackParams
-         * @see #onTimeShiftGetStartPosition
-         * @see #onTimeShiftGetCurrentPosition
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
          */
         public void onTimeShiftSeekTo(long timeMs) {
         }
@@ -905,11 +978,12 @@
          * parameters previously set.
          *
          * @param params The playback params.
-         * @see #onTimeShiftResume
-         * @see #onTimeShiftPause
-         * @see #onTimeShiftSeekTo
-         * @see #onTimeShiftGetStartPosition
-         * @see #onTimeShiftGetCurrentPosition
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
          */
         public void onTimeShiftSetPlaybackParams(PlaybackParams params) {
         }
@@ -925,11 +999,12 @@
          * seek to, thus failure to notifying its change immediately might result in bad experience
          * where the application allows the user to seek to an invalid time position.
          *
-         * @see #onTimeShiftResume
-         * @see #onTimeShiftPause
-         * @see #onTimeShiftSeekTo
-         * @see #onTimeShiftSetPlaybackParams
-         * @see #onTimeShiftGetCurrentPosition
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetCurrentPosition()
          */
         public long onTimeShiftGetStartPosition() {
             return TvInputManager.TIME_SHIFT_INVALID_TIME;
@@ -944,11 +1019,12 @@
          * playback position reported by {@link #onTimeShiftGetStartPosition}. Failure to notifying
          * the correct current position might lead to bad user experience.
          *
-         * @see #onTimeShiftResume
-         * @see #onTimeShiftPause
-         * @see #onTimeShiftSeekTo
-         * @see #onTimeShiftSetPlaybackParams
-         * @see #onTimeShiftGetStartPosition
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
          */
         public long onTimeShiftGetCurrentPosition() {
             return TvInputManager.TIME_SHIFT_INVALID_TIME;
@@ -1263,6 +1339,14 @@
         }
 
         /**
+         * Calls {@link #onTimeShiftPlay(Uri)}.
+         */
+        void timeShiftPlay(Uri recordedProgramUri) {
+            mCurrentPositionMs = 0;
+            onTimeShiftPlay(recordedProgramUri);
+        }
+
+        /**
          * Calls {@link #onTimeShiftPause}.
          */
         void timeShiftPause() {
@@ -1385,7 +1469,7 @@
             }
         }
 
-        private void executeOrPostRunnable(Runnable action) {
+        private void executeOrPostRunnableOnMainThread(Runnable action) {
             synchronized(mLock) {
                 if (mSessionCallback == null) {
                     // The session is not initialized yet.
@@ -1449,6 +1533,267 @@
     }
 
     /**
+     * Base class for derived classes to implement to provide a TV input recording session.
+     */
+    public abstract static class RecordingSession {
+        final Handler mHandler;
+
+        private final Object mLock = new Object();
+        // @GuardedBy("mLock")
+        private ITvInputSessionCallback mSessionCallback;
+        // @GuardedBy("mLock")
+        private final List<Runnable> mPendingActions = new ArrayList<>();
+
+        /**
+         * Creates a new Recording Session for TV program recording.
+         *
+         * @param context The context of the application
+         */
+        public RecordingSession(Context context) {
+            mHandler = new Handler(context.getMainLooper());
+        }
+
+        /**
+         * 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.
+         *
+         * @param recordedProgramUri The URI of the new recorded program.
+         */
+        public void notifyRecordingStopped(final Uri recordedProgramUri) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyRecordingStopped");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onRecordingStopped(recordedProgramUri);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyRecordingStopped", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Sends an error to the application at any moment.
+         *
+         * @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>
+         */
+        public void notifyError(@TvInputManager.RecordingError final int error) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyError");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onError(error);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyError", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Dispatches an event to the application using this recording session.
+         *
+         * @param eventType The type of the event.
+         * @param eventArgs Optional arguments of the event.
+         * @hide
+         */
+        @SystemApi
+        public void notifySessionEvent(@NonNull final String eventType, final Bundle eventArgs) {
+            Preconditions.checkNotNull(eventType);
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifySessionEvent(" + eventType + ")");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onSessionEvent(eventType, eventArgs);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in sending event (event=" + eventType + ")", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Called when the recording session is connected.
+         *
+         * @param channelUri The URI of the channel.
+         */
+        public abstract void onConnect(Uri channelUri);
+
+        /**
+         * Called when the recording session is connected.
+         *
+         * @param channelUri The URI of the channel.
+         * @param params Extra parameters.
+         * @hide
+         */
+        @SystemApi
+        public void onConnect(Uri channelUri, Bundle params) {
+            onConnect(channelUri);
+        }
+
+        /**
+         * Called when the application requests to disconnect the current recording session.
+         */
+        public abstract void onDisconnect();
+
+        /**
+         * Called when the application requests to start recording. Recording must start
+         * immediately.
+         *
+         * <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 call either {@link #notifyRecordingStopped(Uri)} or
+         * {@link #notifyError(int)}}.
+         */
+        public abstract void onStopRecording();
+
+        /**
+         * 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
+         * their clients.
+         *
+         * @param action Name of the command to be performed. This <em>must</em> be a scoped name,
+         *            i.e. prefixed with a package name you own, so that different developers will
+         *            not create conflicting commands.
+         * @param data Any data to include with the command.
+         * @hide
+         */
+        @SystemApi
+        public void onAppPrivateCommand(@NonNull String action, Bundle data) {
+        }
+
+        /**
+         * Calls {@link #onConnect(Uri, Bundle)}.
+         *
+         */
+        void connect(Uri channelUri, Bundle params) {
+            onConnect(channelUri, params);
+        }
+
+        /**
+         * Calls {@link #onDisconnect()}.
+         *
+         */
+        void disconnect() {
+            onDisconnect();
+        }
+
+        /**
+         * Calls {@link #onStartRecording()}.
+         *
+         */
+        void startRecording() {
+            onStartRecording();
+        }
+
+        /**
+         * Calls {@link #onStopRecording()}.
+         *
+         */
+        void stopRecording() {
+            onStopRecording();
+        }
+
+        /**
+         * Calls {@link #onAppPrivateCommand(String, Bundle)}.
+         */
+        void appPrivateCommand(String action, Bundle data) {
+            onAppPrivateCommand(action, data);
+        }
+
+        private void initialize(ITvInputSessionCallback callback) {
+            synchronized(mLock) {
+                mSessionCallback = callback;
+                for (Runnable runnable : mPendingActions) {
+                    runnable.run();
+                }
+                mPendingActions.clear();
+            }
+        }
+
+        private void executeOrPostRunnableOnMainThread(Runnable action) {
+            synchronized(mLock) {
+                if (mSessionCallback == null) {
+                    // The session is not initialized yet.
+                    mPendingActions.add(action);
+                } else {
+                    if (mHandler.getLooper().isCurrentThread()) {
+                        action.run();
+                    } else {
+                        // Posts the runnable if this is not called from the main thread
+                        mHandler.post(action);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
      * Base class for a TV input session which represents an external device connected to a
      * hardware TV input.
      *
@@ -1588,10 +1933,12 @@
     private final class ServiceHandler extends Handler {
         private static final int DO_CREATE_SESSION = 1;
         private static final int DO_NOTIFY_SESSION_CREATED = 2;
-        private static final int DO_ADD_HARDWARE_TV_INPUT = 3;
-        private static final int DO_REMOVE_HARDWARE_TV_INPUT = 4;
-        private static final int DO_ADD_HDMI_TV_INPUT = 5;
-        private static final int DO_REMOVE_HDMI_TV_INPUT = 6;
+        private static final int DO_CREATE_RECORDING_SESSION = 3;
+        private static final int DO_ADD_HARDWARE_TV_INPUT = 4;
+        private static final int DO_REMOVE_HARDWARE_TV_INPUT = 5;
+        private static final int DO_ADD_HDMI_TV_INPUT = 6;
+        private static final int DO_REMOVE_HDMI_TV_INPUT = 7;
+        private static final int DO_SET_TV_INPUT_INFO = 8;
 
         private void broadcastAddHardwareTvInput(int deviceId, TvInputInfo inputInfo) {
             int n = mCallbacks.beginBroadcast();
@@ -1629,6 +1976,18 @@
             mCallbacks.finishBroadcast();
         }
 
+        private void broadcastSetTvInputInfo(String inputId, TvInputInfo inputInfo) {
+            int n = mCallbacks.beginBroadcast();
+            for (int i = 0; i < n; ++i) {
+                try {
+                    mCallbacks.getBroadcastItem(i).setTvInputInfo(inputId, inputInfo);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "error in broadcastSetTvInputInfo", e);
+                }
+            }
+            mCallbacks.finishBroadcast();
+        }
+
         @Override
         public final void handleMessage(Message msg) {
             switch (msg.what) {
@@ -1704,6 +2063,31 @@
                     args.recycle();
                     return;
                 }
+                case DO_CREATE_RECORDING_SESSION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg1;
+                    String inputId = (String) args.arg2;
+                    args.recycle();
+                    RecordingSession recordingSessionImpl = onCreateRecordingSession(inputId);
+                    if (recordingSessionImpl == null) {
+                        try {
+                            // Failed to create a recording session.
+                            cb.onSessionCreated(null, null);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "error in onSessionCreated", e);
+                        }
+                        return;
+                    }
+                    ITvInputSession stub = new ITvInputSessionWrapper(TvInputService.this,
+                            recordingSessionImpl);
+                    try {
+                        cb.onSessionCreated(stub, null);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "error in onSessionCreated", e);
+                    }
+                    recordingSessionImpl.initialize(cb);
+                    return;
+                }
                 case DO_ADD_HARDWARE_TV_INPUT: {
                     TvInputHardwareInfo hardwareInfo = (TvInputHardwareInfo) msg.obj;
                     TvInputInfo inputInfo = onHardwareAdded(hardwareInfo);
@@ -1736,6 +2120,16 @@
                     }
                     return;
                 }
+                case DO_SET_TV_INPUT_INFO: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    String inputId = (String) args.arg1;
+                    TvInputInfo inputInfo = (TvInputInfo) args.arg2;
+                    if (inputInfo != null) {
+                        broadcastSetTvInputInfo(inputId, inputInfo);
+                    }
+                    args.recycle();
+                    return;
+                }
                 default: {
                     Log.w(TAG, "Unhandled message code: " + msg.what);
                     return;
diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java
new file mode 100644
index 0000000..865e000
--- /dev/null
+++ b/media/java/android/media/tv/TvRecordingClient.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import java.util.ArrayDeque;
+import java.util.Queue;
+
+/**
+ * The public interface object used to interact with a specific TV input service for TV program
+ * recording.
+ */
+public class TvRecordingClient {
+    private static final String TAG = "TvRecordingClient";
+    private static final boolean DEBUG = false;
+
+    private final RecordingCallback mCallback;
+    private final Handler mHandler;
+
+    private final TvInputManager mTvInputManager;
+    private TvInputManager.Session mSession;
+    private MySessionCallback mSessionCallback;
+
+    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 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.
+     */
+    public TvRecordingClient(Context context, String tag, @NonNull RecordingCallback callback,
+            Handler handler) {
+        mCallback = callback;
+        mHandler = handler == null ? new Handler(Looper.getMainLooper()) : handler;
+        mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
+    }
+
+    /**
+     * 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.
+     *
+     * <p>The recording session will respond by calling
+     * {@link RecordingCallback#onConnected()} or {@link RecordingCallback#onError(int)}.
+     *
+     * @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);
+    }
+
+    /**
+     * 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.
+     *
+     * <p>The recording session will respond by calling
+     * {@link RecordingCallback#onConnected()} or {@link RecordingCallback#onError(int)}.
+     *
+     * @param inputId The ID of the TV input for the given channel.
+     * @param channelUri The URI of a channel.
+     * @param params Extra parameters.
+     * @hide
+     */
+    @SystemApi
+    public void connect(String inputId, Uri channelUri, Bundle params) {
+        if (DEBUG) Log.d(TAG, "connect(" + channelUri + ")");
+        if (TextUtils.isEmpty(inputId)) {
+            throw new IllegalArgumentException("inputId cannot be null or an empty string");
+        }
+        if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) {
+            if (mSession != null) {
+                mSession.connect(channelUri, params);
+            } else {
+                mSessionCallback.mChannelUri = channelUri;
+                mSessionCallback.mConnectionParams = params;
+            }
+        } else {
+            resetInternal();
+            mSessionCallback = new MySessionCallback(inputId, channelUri, params);
+            if (mTvInputManager != null) {
+                mTvInputManager.createRecordingSession(inputId, mSessionCallback, mHandler);
+            }
+        }
+    }
+
+    /**
+     * 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)}.
+     */
+    public void disconnect() {
+        if (DEBUG) Log.d(TAG, "disconnect()");
+        resetInternal();
+    }
+
+    private void resetInternal() {
+        mSessionCallback = null;
+        mPendingAppPrivateCommands.clear();
+        if (mSession != null) {
+            mSession.release();
+            mSession = null;
+        }
+    }
+
+    /**
+     * Starts TV program recording for the current recording session. It is expected that recording
+     * starts immediately after calling this method.
+     *
+     * <p>The recording session will respond by calling
+     * {@link RecordingCallback#onRecordingStarted()} or {@link RecordingCallback#onError(int)}.
+     */
+    public void startRecording() {
+        if (mSession != null) {
+            mSession.startRecording();
+        }
+    }
+
+    /**
+     * Stops TV program recording for the current recording session. It is expected that recording
+     * stops immediately after calling this method.
+     *
+     * <p>The recording session will respond by calling
+     * {@link RecordingCallback#onRecordingStopped(Uri)} or {@link RecordingCallback#onError(int)}.
+     */
+    public void stopRecording() {
+        if (mSession != null) {
+            mSession.stopRecording();
+        }
+    }
+
+    /**
+     * Calls {@link TvInputService.RecordingSession#appPrivateCommand(String, Bundle)
+     * TvInputService.RecordingSession.appPrivateCommand()} on the current TvView.
+     *
+     * @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
+     *            create conflicting commands.
+     * @param data An optional bundle to send with the command.
+     * @hide
+     */
+    @SystemApi
+    public void sendAppPrivateCommand(@NonNull String action, Bundle data) {
+        if (TextUtils.isEmpty(action)) {
+            throw new IllegalArgumentException("action cannot be null or an empty string");
+        }
+        if (mSession != null) {
+            mSession.sendAppPrivateCommand(action, data);
+        } else {
+            Log.w(TAG, "sendAppPrivateCommand - session not yet created (action \"" + action
+                    + "\" pending)");
+            mPendingAppPrivateCommands.add(Pair.create(action, data));
+        }
+    }
+
+    /**
+     * Callback used to receive various status updates on the
+     * {@link android.media.tv.TvInputService.RecordingSession}
+     */
+    public 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.
+         *
+         * @param recordedProgramUri The URI for the new recorded program.
+         * @see android.media.tv.TvContract.RecordedPrograms
+         */
+        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.
+         *
+         * @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>
+         */
+        public void onError(@TvInputManager.RecordingError int error) {
+        }
+
+        /**
+         * This is invoked when a custom event from the bound TV input is sent to this client.
+         *
+         * @param inputId The ID of the TV input bound to this client.
+         * @param eventType The type of the event.
+         * @param eventArgs Optional arguments of the event.
+         * @hide
+         */
+        @SystemApi
+        public void onEvent(String inputId, String eventType, Bundle eventArgs) {
+        }
+    }
+
+    private class MySessionCallback extends TvInputManager.SessionCallback {
+        final String mInputId;
+        Uri mChannelUri;
+        Bundle mConnectionParams;
+
+        MySessionCallback(String inputId, Uri channelUri, Bundle connectionParams) {
+            mInputId = inputId;
+            mChannelUri = channelUri;
+            mConnectionParams = connectionParams;
+        }
+
+        @Override
+        public void onSessionCreated(TvInputManager.Session session) {
+            if (DEBUG) {
+                Log.d(TAG, "onSessionCreated()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onSessionCreated - session already created");
+                // This callback is obsolete.
+                if (session != null) {
+                    session.release();
+                }
+                return;
+            }
+            mSession = session;
+            if (session != null) {
+                // Sends the pending app private commands.
+                for (Pair<String, Bundle> command : mPendingAppPrivateCommands) {
+                    mSession.sendAppPrivateCommand(command.first, command.second);
+                }
+                mPendingAppPrivateCommands.clear();
+                mSession.connect(mChannelUri, mConnectionParams);
+            } else {
+                mSessionCallback = null;
+                mCallback.onError(TvInputManager.RECORDING_ERROR_CONNECTION_FAILED);
+            }
+        }
+
+        @Override
+        public void onSessionReleased(TvInputManager.Session session) {
+            if (DEBUG) {
+                Log.d(TAG, "onSessionReleased()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onSessionReleased - session not created");
+                return;
+            }
+            mSessionCallback = null;
+            mSession = null;
+            mCallback.onDisconnected();
+        }
+
+        @Override
+        public void onRecordingStarted(TvInputManager.Session session) {
+            if (DEBUG) {
+                Log.d(TAG, "onRecordingStarted()");
+            }
+            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()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onRecordingStopped - session not created");
+                return;
+            }
+            mCallback.onRecordingStopped(recordedProgramUri);
+        }
+
+        @Override
+        public void onError(TvInputManager.Session session, int error) {
+            if (DEBUG) {
+                Log.d(TAG, "onError()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onError - session not created");
+                return;
+            }
+            mCallback.onError(error);
+        }
+
+        @Override
+        public void onSessionEvent(TvInputManager.Session session, String eventType,
+                Bundle eventArgs) {
+            if (DEBUG) {
+                Log.d(TAG, "onSessionEvent(" + eventType + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onSessionEvent - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onEvent(mInputId, eventType, eventArgs);
+            }
+        }
+    }
+}
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 003a274..0132d24 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -448,6 +448,37 @@
     }
 
     /**
+     * Plays a given recorded TV program.
+     *
+     * @param inputId The ID of the TV input that created the given recorded program.
+     * @param recordedProgramUri The URI of a recorded program.
+     */
+    public void timeShiftPlay(String inputId, Uri recordedProgramUri) {
+        if (DEBUG) Log.d(TAG, "timeShiftPlay(" + recordedProgramUri + ")");
+        if (TextUtils.isEmpty(inputId)) {
+            throw new IllegalArgumentException("inputId cannot be null or an empty string");
+        }
+        synchronized (sMainTvViewLock) {
+            if (sMainTvView.get() == null) {
+                sMainTvView = new WeakReference<>(this);
+            }
+        }
+        if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) {
+            if (mSession != null) {
+                mSession.timeShiftPlay(recordedProgramUri);
+            } else {
+                mSessionCallback.mRecordedProgramUri = recordedProgramUri;
+            }
+        } else {
+            resetInternal();
+            mSessionCallback = new MySessionCallback(inputId, recordedProgramUri);
+            if (mTvInputManager != null) {
+                mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+            }
+        }
+    }
+
+    /**
      * Pauses playback. No-op if it is already paused. Call {@link #timeShiftResume} to resume.
      */
     public void timeShiftPause() {
@@ -994,6 +1025,7 @@
         final String mInputId;
         Uri mChannelUri;
         Bundle mTuneParams;
+        Uri mRecordedProgramUri;
 
         MySessionCallback(String inputId, Uri channelUri, Bundle tuneParams) {
             mInputId = inputId;
@@ -1001,6 +1033,11 @@
             mTuneParams = tuneParams;
         }
 
+        MySessionCallback(String inputId, Uri recordedProgramUri) {
+            mInputId = inputId;
+            mRecordedProgramUri = recordedProgramUri;
+        }
+
         @Override
         public void onSessionCreated(Session session) {
             if (DEBUG) {
@@ -1043,7 +1080,11 @@
                 if (mCaptionEnabled != null) {
                     mSession.setCaptionEnabled(mCaptionEnabled);
                 }
-                mSession.tune(mChannelUri, mTuneParams);
+                if (mChannelUri != null) {
+                    mSession.tune(mChannelUri, mTuneParams);
+                } else {
+                    mSession.timeShiftPlay(mRecordedProgramUri);
+                }
                 ensurePositionTracking();
             } else {
                 mSessionCallback = null;
diff --git a/media/java/android/mtp/MtpConstants.java b/media/java/android/mtp/MtpConstants.java
index bdd8643..ef2cf2b 100644
--- a/media/java/android/mtp/MtpConstants.java
+++ b/media/java/android/mtp/MtpConstants.java
@@ -182,6 +182,13 @@
     public static final int FORMAT_MPEG = 0x300B;
     /** Format code for ASF files */
     public static final int FORMAT_ASF = 0x300C;
+    /**
+     * Format code for unknown image files.
+     * <p>
+     * Will be used for the formats which are not specified in PTP specification.
+     * For instance, WEBP and WBMP.
+     */
+    public static final int FORMAT_DEFINED = 0x3800;
     /** Format code for JPEG image files */
     public static final int FORMAT_EXIF_JPEG = 0x3801;
     /** Format code for TIFF EP image files */
@@ -272,12 +279,12 @@
     public static final int FORMAT_MS_POWERPOINT_PRESENTATION = 0xBA86;
 
     /**
-      * Returns true if the object is abstract (that is, it has no representation
-      * in the underlying file system).
-      *
-      * @param format the format of the object
-      * @return true if the object is abstract
-      */
+     * Returns true if the object is abstract (that is, it has no representation
+     * in the underlying file system).
+     *
+     * @param format the format of the object
+     * @return true if the object is abstract
+     */
     public static boolean isAbstractObject(int format) {
         switch (format) {
             case FORMAT_ABSTRACT_MULTIMEDIA_ALBUM:
diff --git a/media/java/android/mtp/MtpDeviceInfo.java b/media/java/android/mtp/MtpDeviceInfo.java
index 1ceca84..2e4f451 100644
--- a/media/java/android/mtp/MtpDeviceInfo.java
+++ b/media/java/android/mtp/MtpDeviceInfo.java
@@ -30,6 +30,7 @@
     private String mVersion;
     private String mSerialNumber;
     private int[] mOperationsSupported;
+    private int[] mEventsSupported;
 
     // only instantiated via JNI
     private MtpDeviceInfo() {
@@ -74,9 +75,71 @@
     /**
      * Returns operation code supported by the device.
      *
-     * @return supported operation code
+     * @return supported operation code. Can be null if device does not provide the property.
+     * @see MtpConstants#OPERATION_GET_DEVICE_INFO
+     * @see MtpConstants#OPERATION_OPEN_SESSION
+     * @see MtpConstants#OPERATION_CLOSE_SESSION
+     * @see MtpConstants#OPERATION_GET_STORAGE_I_DS
+     * @see MtpConstants#OPERATION_GET_STORAGE_INFO
+     * @see MtpConstants#OPERATION_GET_NUM_OBJECTS
+     * @see MtpConstants#OPERATION_GET_OBJECT_HANDLES
+     * @see MtpConstants#OPERATION_GET_OBJECT_INFO
+     * @see MtpConstants#OPERATION_GET_OBJECT
+     * @see MtpConstants#OPERATION_GET_THUMB
+     * @see MtpConstants#OPERATION_DELETE_OBJECT
+     * @see MtpConstants#OPERATION_SEND_OBJECT_INFO
+     * @see MtpConstants#OPERATION_SEND_OBJECT
+     * @see MtpConstants#OPERATION_INITIATE_CAPTURE
+     * @see MtpConstants#OPERATION_FORMAT_STORE
+     * @see MtpConstants#OPERATION_RESET_DEVICE
+     * @see MtpConstants#OPERATION_SELF_TEST
+     * @see MtpConstants#OPERATION_SET_OBJECT_PROTECTION
+     * @see MtpConstants#OPERATION_POWER_DOWN
+     * @see MtpConstants#OPERATION_GET_DEVICE_PROP_DESC
+     * @see MtpConstants#OPERATION_GET_DEVICE_PROP_VALUE
+     * @see MtpConstants#OPERATION_SET_DEVICE_PROP_VALUE
+     * @see MtpConstants#OPERATION_RESET_DEVICE_PROP_VALUE
+     * @see MtpConstants#OPERATION_TERMINATE_OPEN_CAPTURE
+     * @see MtpConstants#OPERATION_MOVE_OBJECT
+     * @see MtpConstants#OPERATION_COPY_OBJECT
+     * @see MtpConstants#OPERATION_GET_PARTIAL_OBJECT
+     * @see MtpConstants#OPERATION_INITIATE_OPEN_CAPTURE
+     * @see MtpConstants#OPERATION_GET_OBJECT_PROPS_SUPPORTED
+     * @see MtpConstants#OPERATION_GET_OBJECT_PROP_DESC
+     * @see MtpConstants#OPERATION_GET_OBJECT_PROP_VALUE
+     * @see MtpConstants#OPERATION_SET_OBJECT_PROP_VALUE
+     * @see MtpConstants#OPERATION_GET_OBJECT_REFERENCES
+     * @see MtpConstants#OPERATION_SET_OBJECT_REFERENCES
+     * @see MtpConstants#OPERATION_SKIP
      */
     public final @Nullable int[] getOperationsSupported() {
         return mOperationsSupported;
     }
+
+    /**
+     * Returns event code supported by the device.
+     *
+     * @return supported event code. Can be null if device does not provide the property.
+     * @see MtpConstants#EVENT_UNDEFINED
+     * @see MtpConstants#EVENT_CANCEL_TRANSACTION
+     * @see MtpConstants#EVENT_OBJECT_ADDED
+     * @see MtpConstants#EVENT_OBJECT_REMOVED
+     * @see MtpConstants#EVENT_STORE_ADDED
+     * @see MtpConstants#EVENT_STORE_REMOVED
+     * @see MtpConstants#EVENT_DEVICE_PROP_CHANGED
+     * @see MtpConstants#EVENT_OBJECT_INFO_CHANGED
+     * @see MtpConstants#EVENT_DEVICE_INFO_CHANGED
+     * @see MtpConstants#EVENT_REQUEST_OBJECT_TRANSFER
+     * @see MtpConstants#EVENT_STORE_FULL
+     * @see MtpConstants#EVENT_DEVICE_RESET
+     * @see MtpConstants#EVENT_STORAGE_INFO_CHANGED
+     * @see MtpConstants#EVENT_CAPTURE_COMPLETE
+     * @see MtpConstants#EVENT_UNREPORTED_STATUS
+     * @see MtpConstants#EVENT_OBJECT_PROP_CHANGED
+     * @see MtpConstants#EVENT_OBJECT_PROP_DESC_CHANGED
+     * @see MtpConstants#EVENT_OBJECT_REFERENCES_CHANGED
+     */
+    public final @Nullable int[] getEventsSupported() {
+        return mEventsSupported;
+    }
 }
diff --git a/media/java/android/service/media/IMediaBrowserService.aidl b/media/java/android/service/media/IMediaBrowserService.aidl
index f01fc07..fe7ebfa 100644
--- a/media/java/android/service/media/IMediaBrowserService.aidl
+++ b/media/java/android/service/media/IMediaBrowserService.aidl
@@ -14,10 +14,19 @@
  * @hide
  */
 oneway interface IMediaBrowserService {
+
+    // Warning: DO NOT CHANGE the methods signature and order of methods.
+    // The change of the order or the method signatures could break the support library.
+
     void connect(String pkg, in Bundle rootHints, IMediaBrowserServiceCallbacks callbacks);
     void disconnect(IMediaBrowserServiceCallbacks callbacks);
 
     void addSubscription(String uri, IMediaBrowserServiceCallbacks callbacks);
     void removeSubscription(String uri, IMediaBrowserServiceCallbacks callbacks);
     void getMediaItem(String uri, in ResultReceiver cb);
-}
\ No newline at end of file
+
+    void addSubscriptionWithOptions(String uri, in Bundle options,
+            IMediaBrowserServiceCallbacks callbacks);
+    void removeSubscriptionWithOptions(String uri, in Bundle options,
+            IMediaBrowserServiceCallbacks callbacks);
+}
diff --git a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
index 2a37ada..dadb025 100644
--- a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
+++ b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
@@ -22,5 +22,5 @@
      */
     void onConnect(String root, in MediaSession.Token session, in Bundle extras);
     void onConnectFailed();
-    void onLoadChildren(String mediaId, in ParceledListSlice list);
+    void onLoadChildren(String mediaId, in ParceledListSlice list, in Bundle options);
 }
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index 8edccac..6cf90d5 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -25,11 +25,12 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.media.browse.MediaBrowser;
+import android.media.browse.MediaBrowserUtils;
 import android.media.session.MediaSession;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.service.media.IMediaBrowserService;
@@ -40,7 +41,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -82,7 +84,9 @@
      */
     public static final String KEY_MEDIA_ITEM = "media_item";
 
-    private final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap();
+    private static final int RESULT_FLAG_OPTION_NOT_HANDLED = 0x00000001;
+
+    private final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap<>();
     private final Handler mHandler = new Handler();
     private ServiceBinder mBinder;
     MediaSession.Token mSession;
@@ -95,7 +99,7 @@
         Bundle rootHints;
         IMediaBrowserServiceCallbacks callbacks;
         BrowserRoot root;
-        HashSet<String> subscriptions = new HashSet();
+        HashMap<String, List<Bundle>> subscriptions = new HashMap<>();
     }
 
     /**
@@ -115,6 +119,7 @@
         private Object mDebug;
         private boolean mDetachCalled;
         private boolean mSendResultCalled;
+        private int mFlag;
 
         Result(Object debug) {
             mDebug = debug;
@@ -128,7 +133,7 @@
                 throw new IllegalStateException("sendResult() called twice for: " + mDebug);
             }
             mSendResultCalled = true;
-            onResultSent(result);
+            onResultSent(result, mFlag);
         }
 
         /**
@@ -151,11 +156,15 @@
             return mDetachCalled || mSendResultCalled;
         }
 
+        void setFlag(int flag) {
+            mFlag = flag;
+        }
+
         /**
          * Called when the result is sent, after assertions about not being called twice
          * have happened.
          */
-        void onResultSent(T result) {
+        void onResultSent(T result, int flag) {
         }
     }
 
@@ -228,9 +237,15 @@
                 });
         }
 
+        @Override
+        public void addSubscription(final String id,
+                final IMediaBrowserServiceCallbacks callbacks) {
+            addSubscriptionWithOptions(id, null, callbacks);
+        }
 
         @Override
-        public void addSubscription(final String id, final IMediaBrowserServiceCallbacks callbacks) {
+        public void addSubscriptionWithOptions(final String id, final Bundle options,
+                final IMediaBrowserServiceCallbacks callbacks) {
             mHandler.post(new Runnable() {
                     @Override
                     public void run() {
@@ -244,7 +259,7 @@
                             return;
                         }
 
-                        MediaBrowserService.this.addSubscription(id, connection);
+                        MediaBrowserService.this.addSubscription(id, connection, options);
                     }
                 });
         }
@@ -252,6 +267,12 @@
         @Override
         public void removeSubscription(final String id,
                 final IMediaBrowserServiceCallbacks callbacks) {
+            removeSubscriptionWithOptions(id, null, callbacks);
+        }
+
+        @Override
+        public void removeSubscriptionWithOptions(final String id, final Bundle options,
+                final IMediaBrowserServiceCallbacks callbacks) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -263,7 +284,7 @@
                                 + id);
                         return;
                     }
-                    if (!connection.subscriptions.remove(id)) {
+                    if (!MediaBrowserService.this.removeSubscription(id, connection, options)) {
                         Log.w(TAG, "removeSubscription called for " + id
                                 + " which is not subscribed");
                     }
@@ -345,6 +366,33 @@
             @NonNull Result<List<MediaBrowser.MediaItem>> result);
 
     /**
+     * Called to get information about the children of a media item.
+     * <p>
+     * Implementations must call {@link Result#sendResult result.sendResult}
+     * with the list of children. If loading the children will be an expensive
+     * operation that should be performed on another thread,
+     * {@link Result#detach result.detach} may be called before returning from
+     * this function, and then {@link Result#sendResult result.sendResult}
+     * called when the loading is complete.
+     *
+     * @param parentId The id of the parent media item whose children are to be
+     *            queried.
+     * @param result The Result to send the list of children to, or null if the
+     *            id is invalid.
+     * @param options A bundle of service-specific arguments sent from the media
+     *            browse. The information returned through the result should be
+     *            affected by the contents of this bundle.
+     */
+    public void onLoadChildren(@NonNull String parentId,
+            @NonNull Result<List<MediaBrowser.MediaItem>> result, @NonNull Bundle options) {
+        // To support backward compatibility, when the implementation of MediaBrowserService doesn't
+        // override onLoadChildren() with options, onLoadChildren() without options will be used
+        // instead, and the options will be applied in the implementation of result.onResultSent().
+        result.setFlag(RESULT_FLAG_OPTION_NOT_HANDLED);
+        onLoadChildren(parentId, result);
+    }
+
+    /**
      * Called to get information about a specific media item.
      * <p>
      * Implementations must call {@link Result#sendResult result.sendResult}. If
@@ -413,7 +461,29 @@
      * @param parentId The id of the parent media item whose
      * children changed.
      */
-    public void notifyChildrenChanged(@NonNull final String parentId) {
+    public void notifyChildrenChanged(@NonNull String parentId) {
+        notifyChildrenChangedInternal(parentId, null);
+    }
+
+    /**
+     * Notifies all connected media browsers that the children of
+     * the specified parent id have changed in some way.
+     * This will cause browsers to fetch subscribed content again.
+     *
+     * @param parentId The id of the parent media item whose
+     *            children changed.
+     * @param options A bundle of service-specific arguments to send
+     *            to the media browse. The contents of this bundle may
+     *            contain the information about the change.
+     */
+    public void notifyChildrenChanged(@NonNull String parentId, @NonNull Bundle options) {
+        if (options == null) {
+            throw new IllegalArgumentException("options cannot be null in notifyChildrenChanged");
+        }
+        notifyChildrenChangedInternal(parentId, options);
+    }
+
+    private void notifyChildrenChangedInternal(final String parentId, final Bundle options) {
         if (parentId == null) {
             throw new IllegalArgumentException("parentId cannot be null in notifyChildrenChanged");
         }
@@ -422,8 +492,13 @@
             public void run() {
                 for (IBinder binder : mConnections.keySet()) {
                     ConnectionRecord connection = mConnections.get(binder);
-                    if (connection.subscriptions.contains(parentId)) {
-                        performLoadChildren(parentId, connection);
+                    List<Bundle> optionsList = connection.subscriptions.get(parentId);
+                    if (optionsList != null) {
+                        for (Bundle bundle : optionsList) {
+                            if (MediaBrowserUtils.hasDuplicatedItems(options, bundle)) {
+                                performLoadChildren(parentId, connection, bundle);
+                            }
+                        }
                     }
                 }
             }
@@ -451,12 +526,42 @@
     /**
      * Save the subscription and if it is a new subscription send the results.
      */
-    private void addSubscription(String id, ConnectionRecord connection) {
+    private void addSubscription(String id, ConnectionRecord connection, Bundle options) {
         // Save the subscription
-        connection.subscriptions.add(id);
-
+        List<Bundle> optionsList = connection.subscriptions.get(id);
+        if (optionsList == null) {
+            optionsList = new ArrayList<>();
+        }
+        for (Bundle bundle : optionsList) {
+            if (MediaBrowserUtils.areSameOptions(options, bundle)) {
+                return;
+            }
+        }
+        optionsList.add(options);
+        connection.subscriptions.put(id, optionsList);
         // send the results
-        performLoadChildren(id, connection);
+        performLoadChildren(id, connection, options);
+    }
+
+    /**
+     * Remove the subscription.
+     */
+    private boolean removeSubscription(String id, ConnectionRecord connection, Bundle options) {
+        boolean removed = false;
+        List<Bundle> optionsList = connection.subscriptions.get(id);
+        if (optionsList != null) {
+            for (Bundle bundle : optionsList) {
+                if (MediaBrowserUtils.areSameOptions(options, bundle)) {
+                    removed = true;
+                    optionsList.remove(bundle);
+                    break;
+                }
+            }
+            if (optionsList.size() == 0) {
+                connection.subscriptions.remove(id);
+            }
+        }
+        return removed;
     }
 
     /**
@@ -464,11 +569,12 @@
      * <p>
      * Callers must make sure that this connection is still connected.
      */
-    private void performLoadChildren(final String parentId, final ConnectionRecord connection) {
+    private void performLoadChildren(final String parentId, final ConnectionRecord connection,
+            final Bundle options) {
         final Result<List<MediaBrowser.MediaItem>> result
                 = new Result<List<MediaBrowser.MediaItem>>(parentId) {
             @Override
-            void onResultSent(List<MediaBrowser.MediaItem> list) {
+            void onResultSent(List<MediaBrowser.MediaItem> list, int flag) {
                 if (mConnections.get(connection.callbacks.asBinder()) != connection) {
                     if (DBG) {
                         Log.d(TAG, "Not sending onLoadChildren result for connection that has"
@@ -477,10 +583,13 @@
                     return;
                 }
 
+                List<MediaBrowser.MediaItem> filteredList =
+                        (flag & RESULT_FLAG_OPTION_NOT_HANDLED) != 0
+                        ? applyOptions(list, options) : list;
                 final ParceledListSlice<MediaBrowser.MediaItem> pls =
-                        list == null ? null : new ParceledListSlice(list);
+                        filteredList == null ? null : new ParceledListSlice<>(filteredList);
                 try {
-                    connection.callbacks.onLoadChildren(parentId, pls);
+                    connection.callbacks.onLoadChildren(parentId, pls, options);
                 } catch (RemoteException ex) {
                     // The other side is in the process of crashing.
                     Log.w(TAG, "Calling onLoadChildren() failed for id=" + parentId
@@ -489,7 +598,11 @@
             }
         };
 
-        onLoadChildren(parentId, result);
+        if (options == null) {
+            onLoadChildren(parentId, result);
+        } else {
+            onLoadChildren(parentId, result, options);
+        }
 
         if (!result.isDone()) {
             throw new IllegalStateException("onLoadChildren must call detach() or sendResult()"
@@ -497,11 +610,29 @@
         }
     }
 
+    private List<MediaBrowser.MediaItem> applyOptions(List<MediaBrowser.MediaItem> list,
+            final Bundle options) {
+        int page = options.getInt(MediaBrowser.EXTRA_PAGE, -1);
+        int pageSize = options.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1);
+        if (page == -1 && pageSize == -1) {
+            return list;
+        }
+        int fromIndex = pageSize * (page - 1);
+        int toIndex = fromIndex + pageSize;
+        if (page < 1 || pageSize < 1 || fromIndex >= list.size()) {
+            return null;
+        }
+        if (toIndex > list.size()) {
+            toIndex = list.size();
+        }
+        return list.subList(fromIndex, toIndex);
+    }
+
     private void performLoadItem(String itemId, final ResultReceiver receiver) {
         final Result<MediaBrowser.MediaItem> result =
                 new Result<MediaBrowser.MediaItem>(itemId) {
             @Override
-            void onResultSent(MediaBrowser.MediaItem item) {
+            void onResultSent(MediaBrowser.MediaItem item, int flag) {
                 Bundle bundle = new Bundle();
                 bundle.putParcelable(KEY_MEDIA_ITEM, item);
                 receiver.send(0, bundle);
diff --git a/media/jni/android_media_ExifInterface.cpp b/media/jni/android_media_ExifInterface.cpp
index 463c17e..42deab4 100644
--- a/media/jni/android_media_ExifInterface.cpp
+++ b/media/jni/android_media_ExifInterface.cpp
@@ -16,92 +16,25 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "ExifInterface_JNI"
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/KeyedVector.h>
 
-#include <android_runtime/AndroidRuntime.h>
-
-#include <jni.h>
-#include <JNIHelp.h>
-
-#include <nativehelper/ScopedLocalRef.h>
+#include "android_media_Utils.h"
 
 #include "src/piex_types.h"
 #include "src/piex.h"
 
+#include <jni.h>
+#include <JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/KeyedVector.h>
+
 // ----------------------------------------------------------------------------
 
 using namespace android;
 
-class FileStream : public piex::StreamInterface {
-private:
-    FILE *mFile;
-    size_t mPosition;
-    size_t mSize;
-
-public:
-    FileStream(const String8 filename)
-        : mPosition(0),
-          mSize(0) {
-        mFile = fopen(filename.string(), "r");
-        if (mFile == NULL) {
-            return;
-        }
-        // Get the size.
-        fseek(mFile, 0l, SEEK_END);
-        mSize = ftell(mFile);
-        fseek(mFile, 0l, SEEK_SET);
-    }
-
-    ~FileStream() {
-        if (mFile != NULL) {
-            fclose(mFile);
-            mFile = NULL;
-        }
-    }
-
-    // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer
-    // provided by the caller, guaranteed to be at least "length" bytes long.
-    // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at
-    // 'offset' bytes from the start of the stream.
-    // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not
-    // change the contents of 'data'.
-    piex::Error GetData(
-            const size_t offset, const size_t length, std::uint8_t* data)
-            override {
-        if (mFile == NULL) {
-            return piex::Error::kFail;
-        }
-
-        // Seek first.
-        if (mPosition != offset) {
-            fseek(mFile, offset, SEEK_SET);
-        }
-
-        // Read bytes.
-        size_t size = fread((void*)data, sizeof(std::uint8_t), length, mFile);
-        mPosition += size;
-
-        // Handle errors.
-        if (ferror(mFile)) {
-            return piex::Error::kFail;
-        }
-        if (size == 0 && feof(mFile)) {
-            return piex::Error::kFail;
-        }
-        return piex::Error::kOk;
-    }
-
-    bool exists() {
-        return mFile != NULL;
-    }
-
-    size_t size() {
-        return mSize;
-    }
-};
-
 #define FIND_CLASS(var, className) \
     var = env->FindClass(className); \
     LOG_FATAL_IF(! var, "Unable to find class " className);
@@ -159,31 +92,10 @@
     env->ReleaseStringUTFChars(jfilename, filenameChars);
 
     piex::PreviewImageData image_data;
-    memset(&image_data, 0, sizeof(image_data));
     std::unique_ptr<FileStream> stream(new FileStream(filename));
 
-    if (!stream.get()->exists()) {
-        // File is not exists.
-        ALOGI("File is not exists: %s", filename.string());
-        return NULL;
-    }
-
-    if (!piex::IsRaw(stream.get())) {
-        // Format not supported.
-        ALOGI("Format not supported: %s", filename.string());
-        return NULL;
-    }
-
-    piex::Error err = piex::GetPreviewImageData(stream.get(), &image_data);
-    if (err != piex::Error::kOk) {
-        // The input data seems to be broken.
-        ALOGI("Raw image not detected: %s (error code: %d)", filename.string(), (int32_t)err);
-        return NULL;
-    }
-
-    if (image_data.thumbnail_offset + image_data.thumbnail_length > stream.get()->size()) {
-        // Corrupted file.
-        ALOGI("Corrupted file: %s", filename.string());
+    if (!GetExifFromRawImage(stream.get(), filename, image_data)) {
+        ALOGI("Raw image not detected: %s", filename.string());
         return NULL;
     }
 
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 1c043e0..4ac62f5 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -574,6 +574,7 @@
         case HAL_PIXEL_FORMAT_Y8:
             // Single plane 8bpp data.
             ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pixelStride = 1;
             break;
         case HAL_PIXEL_FORMAT_YV12:
             pixelStride = 1;
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index e101709..5108eb5 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -28,6 +28,90 @@
 
 namespace android {
 
+FileStream::FileStream(const String8 filename)
+    : mPosition(0),
+      mSize(0) {
+    mFile = fopen(filename.string(), "r");
+    if (mFile == NULL) {
+        return;
+    }
+    // Get the size.
+    fseek(mFile, 0l, SEEK_END);
+    mSize = ftell(mFile);
+    fseek(mFile, 0l, SEEK_SET);
+}
+
+FileStream::~FileStream() {
+    if (mFile != NULL) {
+        fclose(mFile);
+        mFile = NULL;
+    }
+}
+
+piex::Error FileStream::GetData(
+        const size_t offset, const size_t length, std::uint8_t* data) {
+    if (mFile == NULL) {
+        return piex::Error::kFail;
+    }
+
+    // Seek first.
+    if (mPosition != offset) {
+        fseek(mFile, offset, SEEK_SET);
+    }
+
+    // Read bytes.
+    size_t size = fread((void*)data, sizeof(std::uint8_t), length, mFile);
+    mPosition += size;
+
+    // Handle errors.
+    if (ferror(mFile) || (size == 0 && feof(mFile))) {
+        ALOGV("GetData read failed: (offset: %zu, length: %zu)", offset, length);
+        return piex::Error::kFail;
+    }
+    return piex::Error::kOk;
+}
+
+bool FileStream::exists() const {
+    return mFile != NULL;
+}
+
+size_t FileStream::size() const {
+    return mSize;
+}
+
+bool GetExifFromRawImage(
+        FileStream* stream, const String8& filename, piex::PreviewImageData& image_data) {
+    memset(&image_data, 0, sizeof(image_data));
+
+    if (!stream->exists()) {
+        // File is not exists.
+        ALOGV("File is not exists: %s", filename.string());
+        return false;
+    }
+
+    if (!piex::IsRaw(stream)) {
+        // Format not supported.
+        ALOGV("Format not supported: %s", filename.string());
+        return false;
+    }
+
+    piex::Error err = piex::GetPreviewImageData(stream, &image_data);
+
+    if (err != piex::Error::kOk) {
+        // The input data seems to be broken.
+        ALOGV("Raw image not detected: %s (piex error code: %d)", filename.string(), (int32_t)err);
+        return false;
+    }
+
+    if (image_data.thumbnail_offset + image_data.thumbnail_length > stream->size()) {
+        // Corrupted image.
+        ALOGV("Corrupted file: %s", filename.string());
+        return false;
+    }
+
+    return true;
+}
+
 bool ConvertKeyValueArraysToKeyedVector(
         JNIEnv *env, jobjectArray keys, jobjectArray values,
         KeyedVector<String8, String8>* keyedVector) {
diff --git a/media/jni/android_media_Utils.h b/media/jni/android_media_Utils.h
index 635bceb..762c904 100644
--- a/media/jni/android_media_Utils.h
+++ b/media/jni/android_media_Utils.h
@@ -17,21 +17,48 @@
 #ifndef _ANDROID_MEDIA_UTILS_H_
 #define _ANDROID_MEDIA_UTILS_H_
 
-#include "jni.h"
-#include "JNIHelp.h"
-#include "android_runtime/AndroidRuntime.h"
+#include "src/piex_types.h"
+#include "src/piex.h"
 
+#include <android_runtime/AndroidRuntime.h>
+#include <jni.h>
+#include <JNIHelp.h>
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
 
 namespace android {
 
-/**
- * Returns true if the conversion is successful; otherwise, false.
- */
+class FileStream : public piex::StreamInterface {
+private:
+    FILE *mFile;
+    size_t mPosition;
+    size_t mSize;
+
+public:
+    FileStream(const String8 filename);
+    ~FileStream();
+
+    // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer
+    // provided by the caller, guaranteed to be at least "length" bytes long.
+    // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at
+    // 'offset' bytes from the start of the stream.
+    // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not
+    // change the contents of 'data'.
+    piex::Error GetData(
+            const size_t offset, const size_t length, std::uint8_t* data) override;
+    bool exists() const;
+    size_t size() const;
+};
+
+// Reads EXIF metadata from a given raw image via piex.
+// And returns true if the operation is successful; otherwise, false.
+bool GetExifFromRawImage(
+        FileStream* stream, const String8& filename, piex::PreviewImageData& image_data);
+
+// Returns true if the conversion is successful; otherwise, false.
 bool ConvertKeyValueArraysToKeyedVector(
-    JNIEnv *env, jobjectArray keys, jobjectArray values,
-    KeyedVector<String8, String8>* vector);
+        JNIEnv *env, jobjectArray keys, jobjectArray values,
+        KeyedVector<String8, String8>* vector);
 
 struct AMessage;
 status_t ConvertMessageToMap(
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index ec2f98a..556f2c7 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -17,25 +17,17 @@
 #define LOG_TAG "MtpDatabaseJNI"
 #include "utils/Log.h"
 
-#include <assert.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "android_runtime/Log.h"
-
+#include "android_media_Utils.h"
+#include "mtp.h"
 #include "MtpDatabase.h"
 #include "MtpDataPacket.h"
 #include "MtpObjectInfo.h"
 #include "MtpProperty.h"
 #include "MtpStringBuffer.h"
 #include "MtpUtils.h"
-#include "mtp.h"
+
+#include "src/piex_types.h"
+#include "src/piex.h"
 
 extern "C" {
 #include "libexif/exif-content.h"
@@ -44,6 +36,19 @@
 #include "libexif/exif-utils.h"
 }
 
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/Log.h>
+#include <jni.h>
+#include <JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include <assert.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
+
 using namespace android;
 
 // ----------------------------------------------------------------------------
@@ -823,24 +828,48 @@
     env->ReleaseCharArrayElements(mStringBuffer, str, 0);
 
     // read EXIF data for thumbnail information
-    if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
+    switch (info.mFormat) {
+        case MTP_FORMAT_EXIF_JPEG:
+        case MTP_FORMAT_JFIF: {
+            ExifData *exifdata = exif_data_new_from_file(path);
+            if (exifdata) {
+                if ((false)) {
+                    exif_data_foreach_content(exifdata, foreachcontent, NULL);
+                }
 
-        ExifData *exifdata = exif_data_new_from_file(path);
-        if (exifdata) {
-            if ((false)) {
-                exif_data_foreach_content(exifdata, foreachcontent, NULL);
+                ExifEntry *w = exif_content_get_entry(
+                        exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_X_DIMENSION);
+                ExifEntry *h = exif_content_get_entry(
+                        exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_Y_DIMENSION);
+                info.mThumbCompressedSize = exifdata->data ? exifdata->size : 0;
+                info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
+                info.mImagePixWidth = w ? getLongFromExifEntry(w) : 0;
+                info.mImagePixHeight = h ? getLongFromExifEntry(h) : 0;
+                exif_data_unref(exifdata);
+            }
+            break;
+        }
+
+        // Except DNG, all supported RAW image formats are not defined in PTP 1.2 specification.
+        // Most of RAW image formats are based on TIFF or TIFF/EP. To render Fuji's RAF format,
+        // it checks MTP_FORMAT_DEFINED case since it's designed as a custom format.
+        case MTP_FORMAT_DNG:
+        case MTP_FORMAT_TIFF:
+        case MTP_FORMAT_TIFF_EP:
+        case MTP_FORMAT_DEFINED: {
+            std::unique_ptr<FileStream> stream(new FileStream(path));
+            piex::PreviewImageData image_data;
+            if (!GetExifFromRawImage(stream.get(), path, image_data)) {
+                // Couldn't parse EXIF data from a image file via piex.
+                break;
             }
 
-            // XXX get this from exif, or parse jpeg header instead?
-            ExifEntry *w = exif_content_get_entry(
-                    exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_X_DIMENSION);
-            ExifEntry *h = exif_content_get_entry(
-                    exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_Y_DIMENSION);
-            info.mThumbCompressedSize = exifdata->data ? exifdata->size : 0;
+            info.mThumbCompressedSize = image_data.thumbnail_length;
             info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
-            info.mImagePixWidth = w ? getLongFromExifEntry(w) : 0;
-            info.mImagePixHeight = h ? getLongFromExifEntry(h) : 0;
-            exif_data_unref(exifdata);
+            info.mImagePixWidth = image_data.full_width;
+            info.mImagePixHeight = image_data.full_height;
+
+            break;
         }
     }
 
@@ -855,19 +884,55 @@
     void* result = NULL;
     outThumbSize = 0;
 
-    if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK
-            && (format == MTP_FORMAT_EXIF_JPEG || format == MTP_FORMAT_JFIF)) {
-
-        ExifData *exifdata = exif_data_new_from_file(path);
-        if (exifdata) {
-            if (exifdata->data) {
-                result = malloc(exifdata->size);
-                if (result) {
-                    memcpy(result, exifdata->data, exifdata->size);
-                    outThumbSize = exifdata->size;
+    if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK) {
+        switch (format) {
+            case MTP_FORMAT_EXIF_JPEG:
+            case MTP_FORMAT_JFIF: {
+                ExifData *exifdata = exif_data_new_from_file(path);
+                if (exifdata) {
+                    if (exifdata->data) {
+                        result = malloc(exifdata->size);
+                        if (result) {
+                            memcpy(result, exifdata->data, exifdata->size);
+                            outThumbSize = exifdata->size;
+                        }
+                    }
+                    exif_data_unref(exifdata);
                 }
+                break;
             }
-            exif_data_unref(exifdata);
+
+            // See the above comment on getObjectInfo() method.
+            case MTP_FORMAT_DNG:
+            case MTP_FORMAT_TIFF:
+            case MTP_FORMAT_TIFF_EP:
+            case MTP_FORMAT_DEFINED: {
+                std::unique_ptr<FileStream> stream(new FileStream(path));
+                piex::PreviewImageData image_data;
+                if (!GetExifFromRawImage(stream.get(), path, image_data)) {
+                    // Couldn't parse EXIF data from a image file via piex.
+                    break;
+                }
+
+                if (image_data.thumbnail_length == 0) {
+                    // No thumbnail.
+                    break;
+                }
+
+                result = malloc(image_data.thumbnail_length);
+                if (result) {
+                    piex::Error err = stream.get()->GetData(
+                            image_data.thumbnail_offset,
+                            image_data.thumbnail_length,
+                            (std::uint8_t *)result);
+                    if (err == piex::Error::kOk) {
+                        outThumbSize = image_data.thumbnail_length;
+                    } else {
+                        free(result);
+                    }
+                }
+                break;
+            }
         }
     }
 
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index b1b3b62..8b7a926 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -25,6 +25,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 
+#include <memory>
+
 #include "jni.h"
 #include "JNIHelp.h"
 #include "ScopedPrimitiveArray.h"
@@ -66,6 +68,7 @@
 static jfieldID field_deviceInfo_version;
 static jfieldID field_deviceInfo_serialNumber;
 static jfieldID field_deviceInfo_operationsSupported;
+static jfieldID field_deviceInfo_eventsSupported;
 
 // MtpStorageInfo fields
 static jfieldID field_storageInfo_storageId;
@@ -216,7 +219,7 @@
         ALOGD("android_mtp_MtpDevice_get_device_info device is null");
         return NULL;
     }
-    MtpDeviceInfo* deviceInfo = device->getDeviceInfo();
+    std::unique_ptr<MtpDeviceInfo> deviceInfo(device->getDeviceInfo());
     if (!deviceInfo) {
         ALOGD("android_mtp_MtpDevice_get_device_info deviceInfo is null");
         return NULL;
@@ -224,7 +227,6 @@
     jobject info = env->NewObject(clazz_deviceInfo, constructor_deviceInfo);
     if (info == NULL) {
         ALOGE("Could not create a MtpDeviceInfo object");
-        delete deviceInfo;
         return NULL;
     }
 
@@ -242,17 +244,35 @@
             env->NewStringUTF(deviceInfo->mSerial));
     if (deviceInfo->mOperations) {
         const size_t size = deviceInfo->mOperations->size();
-        const jintArray operations = env->NewIntArray(size);
+        ScopedLocalRef<jintArray> operations(env, static_cast<jintArray>(env->NewIntArray(size)));
         {
-            ScopedIntArrayRW elements(env, operations);
+            ScopedIntArrayRW elements(env, operations.get());
+            if (elements.get() == NULL) {
+                ALOGE("Could not create operationsSupported element.");
+                return NULL;
+            }
             for (size_t i = 0; i < size; ++i) {
                 elements[i] = deviceInfo->mOperations->itemAt(i);
             }
+            env->SetObjectField(info, field_deviceInfo_operationsSupported, operations.get());
         }
-        env->SetObjectField(info, field_deviceInfo_operationsSupported, operations);
+    }
+    if (deviceInfo->mEvents) {
+        const size_t size = deviceInfo->mEvents->size();
+        ScopedLocalRef<jintArray> events(env, static_cast<jintArray>(env->NewIntArray(size)));
+        {
+            ScopedIntArrayRW elements(env, events.get());
+            if (elements.get() == NULL) {
+                ALOGE("Could not create eventsSupported element.");
+                return NULL;
+            }
+            for (size_t i = 0; i < size; ++i) {
+                elements[i] = deviceInfo->mEvents->itemAt(i);
+            }
+            env->SetObjectField(info, field_deviceInfo_eventsSupported, events.get());
+        }
     }
 
-    delete deviceInfo;
     return info;
 }
 
@@ -686,6 +706,11 @@
         ALOGE("Can't find MtpDeviceInfo.mOperationsSupported");
         return -1;
     }
+    field_deviceInfo_eventsSupported = env->GetFieldID(clazz, "mEventsSupported", "[I");
+    if (field_deviceInfo_eventsSupported == NULL) {
+        ALOGE("Can't find MtpDeviceInfo.mEventsSupported");
+        return -1;
+    }
     clazz_deviceInfo = (jclass)env->NewGlobalRef(clazz);
 
     clazz = env->FindClass("android/mtp/MtpStorageInfo");
diff --git a/native/android/choreographer.cpp b/native/android/choreographer.cpp
index cc2fd77..e35c85b 100644
--- a/native/android/choreographer.cpp
+++ b/native/android/choreographer.cpp
@@ -82,7 +82,7 @@
 };
 
 
-thread_local Choreographer* gChoreographer;
+static thread_local Choreographer* gChoreographer;
 Choreographer* Choreographer::getForThread() {
     if (gChoreographer == nullptr) {
         sp<Looper> looper = Looper::getForThread();
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 9c01f4f..f37ec58 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -1291,6 +1291,7 @@
                 boolean createGlInterface = false;
                 boolean lostEglContext = false;
                 boolean sizeChanged = false;
+                boolean wantRenderNotification = false;
                 boolean doRenderNotification = false;
                 boolean askedToReleaseEglContext = false;
                 int w = 0;
@@ -1448,6 +1449,9 @@
                                     }
                                     mRequestRender = false;
                                     sGLThreadManager.notifyAll();
+                                    if (mWantRenderNotification) {
+                                        wantRenderNotification = true;
+                                    }
                                     break;
                                 }
                             }
@@ -1574,8 +1578,9 @@
                             break;
                     }
 
-                    if (mWantRenderNotification) {
+                    if (wantRenderNotification) {
                         doRenderNotification = true;
+                        wantRenderNotification = false;
                     }
                 }
 
@@ -1625,11 +1630,21 @@
 
         public void requestRenderAndWait() {
             synchronized(sGLThreadManager) {
+                // If we are already on the GL thread, this means a client callback
+                // has caused reentrancy, for example via updating the SurfaceView parameters.
+                // We will return to the client rendering code, so here we don't need to
+                // do anything.
+                if (Thread.currentThread() == this) {
+                    return;
+                }
+
                 mWantRenderNotification = true;
                 mRequestRender = true;
                 mRenderComplete = false;
+
                 sGLThreadManager.notifyAll();
-                while (!mExited && !mPaused && mRenderComplete == false) {
+
+                while (!mExited && !mPaused && !mRenderComplete && ableToDraw()) {
                     try {
                         sGLThreadManager.wait();
                     } catch (InterruptedException ex) {
@@ -1726,6 +1741,16 @@
                 mSizeChanged = true;
                 mRequestRender = true;
                 mRenderComplete = false;
+
+                // If we are already on the GL thread, this means a client callback
+                // has caused reentrancy, for example via updating the SurfaceView parameters.
+                // We need to process the size change eventually though and update our EGLSurface.
+                // So we set the parameters and return so they can be processed on our
+                // next iteration.
+                if (Thread.currentThread() == this) {
+                    return;
+                }
+
                 sGLThreadManager.notifyAll();
 
                 // Wait for thread to react to resize and render a frame
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index 6beef44..c3452d5 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -78,6 +78,16 @@
             </intent-filter>
         </activity>
 
+        <activity
+            android:name=".OpenExternalDirectoryActivity"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.OPEN_EXTERNAL_DIRECTORY" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="file" />
+            </intent-filter>
+        </activity>
+
         <provider
             android:name=".RecentsProvider"
             android:authorities="com.android.documentsui.recents"
diff --git a/packages/DocumentsUI/res/layout/dialog_create_dir.xml b/packages/DocumentsUI/res/layout/dialog_file_name.xml
similarity index 100%
rename from packages/DocumentsUI/res/layout/dialog_create_dir.xml
rename to packages/DocumentsUI/res/layout/dialog_file_name.xml
diff --git a/packages/DocumentsUI/res/layout/item_dir_grid.xml b/packages/DocumentsUI/res/layout/item_dir_grid.xml
index a08e029..b0331be 100644
--- a/packages/DocumentsUI/res/layout/item_dir_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_dir_grid.xml
@@ -17,7 +17,7 @@
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
+    android:layout_height="wrap_content"
     android:layout_margin="@dimen/grid_item_margin"
     android:background="@color/item_doc_background"
     android:elevation="5dp"
diff --git a/packages/DocumentsUI/res/menu/mode_directory.xml b/packages/DocumentsUI/res/menu/mode_directory.xml
index 4ff396f..6f9bfb5 100644
--- a/packages/DocumentsUI/res/menu/mode_directory.xml
+++ b/packages/DocumentsUI/res/menu/mode_directory.xml
@@ -48,4 +48,9 @@
         android:title="@string/menu_move"
         android:showAsAction="never"
         android:visible="false" />
+    <item
+        android:id="@+id/menu_rename"
+        android:title="@string/menu_rename"
+        android:showAsAction="never"
+        android:visible="false" />
 </menu>
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 1599178..9931a6b 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Toestelle"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Nog programme"</string>
     <string name="empty" msgid="7858882803708117596">"Geen items nie"</string>
+    <string name="no_results" msgid="6622510343880730446">"Geen passings in %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Kan lêer nie oopmaak nie"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Kan sommige dokumente nie uitvee nie"</string>
     <string name="share_via" msgid="8966594246261344259">"Deel via"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Ontdoen"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Maak tans gereed vir kopieer …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Berei tans voor vir skuif …"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Maak tans gereed om uit te vee …"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> lêers nie kopieer nie</item>
       <item quantity="one">Kon <xliff:g id="COUNT_0">%1$d</xliff:g> lêer nie kopieer nie</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> lêers nie skuif nie</item>
       <item quantity="one">Kon <xliff:g id="COUNT_0">%1$d</xliff:g> lêer nie skuif nie</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Raak om besonderhede te bekyk"</string>
-    <string name="retry" msgid="7564024179122207376">"Herprobeer"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> lêers nie uitvee nie</item>
+      <item quantity="one">Kon <xliff:g id="COUNT_0">%1$d</xliff:g> lêer nie uitvee nie</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Tik om besonderhede te bekyk"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Hierdie lêers is nie gekopieer nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Hierdie lêers is nie geskuif nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Het <xliff:g id="COUNT_0">%1$d</xliff:g> lêer na die knipbord gekopieer.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Kan nie die geselekteerde lêers in hierdie ligging plak nie."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Hernoem"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Kon nie dokument hernoem nie"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index 1a6c85a..cccaf51 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"መሣሪያዎች"</string>
     <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="1339885974067891667">"ፋይል መክፈት አይቻልም"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"አንዳንድ ሰነዶችን መሰረዝ አልተቻለም"</string>
     <string name="share_via" msgid="8966594246261344259">"በሚከተለው በኩል ያጋሩ"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"ቀልብስ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"ቅጂ በማዘጋጀት ላይ…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ለመውሰድ በማዘጋጀት ላይ…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"ለመሰረዝ በመዘጋጀት ላይ…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"ዝርዝሮችን ለመመልከት ይንኩ።"</string>
-    <string name="retry" msgid="7564024179122207376">"እንደገና ይሞክሩ"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"እነዚህ ፋይሎች አልተቀዱም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"እነዚህ ፋይሎች አልተወሰዱም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች ወደ ቅንጥብ ሰሌዳ ቀድተዋል።</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"የተመረጡትን ፋይሎች ወደዚህ አካባቢ መለጠፍ አይቻልም።"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"እንደገና ሰይም"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ሰነዱን ዳግም መሰየም አልተሳካም"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index 1e86c03..1177de7 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"أجهزة"</string>
     <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="1339885974067891667">"لا يمكن فتح الملف"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"تعذر حذف بعض المستندات"</string>
     <string name="share_via" msgid="8966594246261344259">"مشاركة عبر"</string>
@@ -96,6 +97,7 @@
     <string name="undo" msgid="7905788502491742328">"تراجع"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"جارٍ التحضير للنسخ ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"جارٍ التحضير للنقل…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"جارٍ الإعداد للحذف…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="zero">لم يتعذر نسخ أية ملفات (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
       <item quantity="two">تعذر نسخ ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
@@ -112,8 +114,17 @@
       <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="4483108577842961665">"المس لعرض التفاصيل"</string>
-    <string name="retry" msgid="7564024179122207376">"إعادة المحاولة"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="zero">تعذر حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملف</item>
+      <item quantity="two">تعذر حذف ملفين (<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>
+      <item quantity="one">تعذر حذف <xliff:g id="COUNT_0">%1$d</xliff:g> ملف</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"انقر لعرض التفاصيل."</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"لم يتم نسخ هذه الملفات: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"لم يتم نقل الملفات التالية: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -125,4 +136,6 @@
       <item quantity="one">تم نسخ ملف واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>) إلى الحافظة.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"يتعذر لصق الملفات المحددة في هذا الموقع."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"إعادة تسمية"</string>
+    <string name="rename_error" msgid="4203041674883412606">"أخفقت إعادة تسمية المستند."</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
index b6dd297..2482ff0 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Cihazlar"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Daha çox tətbiq"</string>
     <string name="empty" msgid="7858882803708117596">"Element yoxdur"</string>
+    <string name="no_results" msgid="6622510343880730446">"%1$s ilə heç bir uyğunluq yoxdur"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Faylı aça bilmir"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Bəzi sənədləri silə bilmir"</string>
     <string name="share_via" msgid="8966594246261344259">"Bunun vasitəsilə paylaş:"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Ləğv edin"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopyalanmaq üçün hazırlanır ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Köçürmə üçün hazırlanır..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Silmək üçün hazırlanır..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl kopyalanmadı</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl kopyalanmadı</item>
@@ -92,8 +94,13 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl köçürülə bilmədi</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl köçürülə bilmədi</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Detallara baxmaq üçün toxunun"</string>
-    <string name="retry" msgid="7564024179122207376">"Yenidən cəhd edin"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> fayl silinmədi</item>
+      <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> fayl silinmədi</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Detallara baxmaq üçün basın"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Bu fayllar kopyalanmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Bu fayllar köçürülmədi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl buferə kopyalandı.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Seçilmiş faylları bu məkana yerləşdirmək olmaz."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Adını dəyişdirin"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Sənəd adını dəyişmək uğursuz oldu"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
index feace71..28a35c7 100644
--- a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Uređaji"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"Nije moguće otvoriti datoteku"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće izbrisati neke dokumente"</string>
     <string name="share_via" msgid="8966594246261344259">"Delite preko"</string>
@@ -87,6 +88,7 @@
     <string name="undo" msgid="7905788502491742328">"Opozovi"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -97,8 +99,14 @@
       <item quantity="few">Nije uspelo premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke</item>
       <item quantity="other">Nije uspelo premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Dodirnite da biste videli detalje"</string>
-    <string name="retry" msgid="7564024179122207376">"Pokušaj ponovo"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Sledeće datoteke nisu kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Ove datoteke nisu premeštene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -107,4 +115,6 @@
       <item quantity="other">Kopirali ste <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka u privremenu memoriju.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Izabrane datoteke ne mogu da se nalepe na ovoj lokaciji."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Preimenuj"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Preimenovanje dokumenta nije uspelo"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index f4aff3e..bdebffb 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Устройства"</string>
     <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="1339885974067891667">"Файлът не може да се отвори"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Някои документи не могат да бъдат изтрити"</string>
     <string name="share_via" msgid="8966594246261344259">"Споделяне чрез"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Отмяна"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Подготвя се за копиране…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Преместването се подготвя…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Подготвя се за изтриване..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"Докоснете, за да видите подробностите"</string>
-    <string name="retry" msgid="7564024179122207376">"Нов опит"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Следните файлове не бяха копирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Следните файлове не бяха преместени: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Копирахте <xliff:g id="COUNT_0">%1$d</xliff:g> файл в буферната памет.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Избраните файлове не могат да се поставят на това място."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Преименуване"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Преименуването на документа не бе успешно"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index c757eaf..0ede613 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"ডিভাইসগুলি"</string>
     <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="1339885974067891667">"ফাইল খোলা যাবে না"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"কিছু দস্তাবেজ মুছতে অসমর্থ"</string>
     <string name="share_via" msgid="8966594246261344259">"এর মাধ্যমে ভাগ করুন"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"পূর্বাবস্থায় ফিরুন"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"অনুলিপি করার জন্য প্রস্তুত করা হচ্ছে..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"সরানোর জন্য প্রস্তুত হচ্ছে..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"মোছার জন্য প্রস্তুত করা হচ্ছে..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"বিশদ বিবরণ দেখতে স্পর্শ করুন"</string>
-    <string name="retry" msgid="7564024179122207376">"পুনরায় চেষ্টা করুন"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"এই ফাইলগুলির প্রতিলিপি করা হয় নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"এই ফাইলগুলি সরানো হয়নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল ক্লিপবোর্ডে প্রতিলিপি করা হয়েছে।</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"এই স্থানে নির্বাচিত ফাইলগুলি আটকানো যাবে না।"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"পুনঃনামকরণ"</string>
+    <string name="rename_error" msgid="4203041674883412606">"দস্তাবেজের পুনঃনামকরণ ব্যর্থ হয়েছে৷"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-bs-rBA/config.xml b/packages/DocumentsUI/res/values-bs-rBA/config.xml
new file mode 100644
index 0000000..843a8aa
--- /dev/null
+++ b/packages/DocumentsUI/res/values-bs-rBA/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-bs-rBA/strings.xml b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
new file mode 100644
index 0000000..bba1053
--- /dev/null
+++ b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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 />
+    <!-- no translation found for menu_settings (6008033148948428823) -->
+    <skip />
+    <!-- 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_show (5792182900084144261) -->
+    <skip />
+    <!-- no translation found for menu_advanced_hide (4218809952721972589) -->
+    <skip />
+    <!-- no translation found for menu_advanced_hide (4845869969015718848) -->
+    <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 (1222448261663503501) -->
+    <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="no_results" msgid="6622510343880730446">"Nema utakmica u %1$s"</string>
+    <!-- no translation found for toast_no_application (1339885974067891667) -->
+    <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="delete_preparing" msgid="5655813182533491992">"Pripremanje za brisanje…"</string>
+    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <!-- no translation found for move_error_notification_title (2779299594174898891) -->
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="one">Nije bilo moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteku</item>
+      <item quantity="few">Nije bilo moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke</item>
+      <item quantity="other">Nije bilo moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Dodirnite za prikaz detalja"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
+    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
+    <skip />
+    <!-- no translation found for move_failure_alert_content (7151140279020481180) -->
+    <skip />
+    <!-- no translation found for clipboard_files_clipped (855459017537058539) -->
+    <!-- no translation found for clipboard_files_cannot_paste (2878324825602325706) -->
+    <skip />
+    <string name="menu_rename" msgid="7678802479104285353">"Preimenuj"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Nije uspjelo preimenovanje dokumenta"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index f01624a..93e92cc 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Dispositius"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Desfés"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Toca per veure els detalls"</string>
-    <string name="retry" msgid="7564024179122207376">"Torna-ho a provar"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Aquests fitxers no s\'han copiat: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Aquests fitxers no s\'han mogut: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">S\'ha copiat <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer al porta-retalls.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"No s\'han pogut enganxar els fitxers seleccionats en aquesta ubicació."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Canvia el nom"</string>
+    <string name="rename_error" msgid="4203041674883412606">"No s\'ha pogut canviar el nom del document"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index 7c70809..ef2b554 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Zařízení"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -90,6 +91,7 @@
     <string name="undo" msgid="7905788502491742328">"Vrátit zpět"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="few">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> soubory</item>
       <item quantity="many">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> souboru</item>
@@ -102,8 +104,15 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Podrobnosti zobrazíte klepnutím"</string>
-    <string name="retry" msgid="7564024179122207376">"Opakovat"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Tyto soubory nebyly zkopírovány: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Následující soubory nebyly přesunuty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -113,4 +122,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> soubor byl zkopírován do schránky.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Vybrané soubory nelze vložit do tohoto umístění."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Přejmenovat"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Dokument se nepodařilo přejmenovat."</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index ef7819a..b80ec57 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Enheder"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Fortryd"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke kopieret</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke kopieret</item>
@@ -92,8 +94,13 @@
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke flyttet</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke flyttet</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Tryk for at se yderligere oplysninger."</string>
-    <string name="retry" msgid="7564024179122207376">"Prøv igen"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Disse filer blev ikke kopieret: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Følgende filer blev ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev kopieret til udklipsholder.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"De valgte filer kan ikke indsættes på denne placering."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Omdøb"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Dokumentet kunne ikke omdøbes"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index 83eb8e0..1363428 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Geräte"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Rückgängig machen"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Zum Einblenden von Details tippen"</string>
-    <string name="retry" msgid="7564024179122207376">"Erneut versuchen"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Diese Dateien wurden nicht kopiert: <xliff:g id="LIST">%1$s</xliff:g>."</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Diese Dateien wurden nicht verschoben: <xliff:g id="LIST">%1$s</xliff:g>."</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei wurde in die Zwischenablage kopiert.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Die ausgewählten Dateien können an diesem Ort nicht eingefügt werden."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Umbenennen"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Dokument konnte nicht umbenannt werden"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index 42959af..a1d28f5 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Συσκευές"</string>
     <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="1339885974067891667">"Δεν είναι δυνατό το άνοιγμα του αρχείου"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Δεν είναι δυνατή η διαγραφή ορισμένων εγγράφων"</string>
     <string name="share_via" msgid="8966594246261344259">"Κοινή χρήση μέσω"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Αναίρεση"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Προετοιμασία για αντιγραφή…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Προετοιμασία για μετακίνηση…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Προετοιμασία για διαγραφή…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"Αγγίξτε για προβολή λεπτομερειών"</string>
-    <string name="retry" msgid="7564024179122207376">"Επανάληψη"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Αυτά τα αρχεία δεν αντιγράφηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Αυτά τα αρχεία δεν μετακινήθηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> αρχείο αντιγράφηκε στο πρόχειρο.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Δεν είναι δυνατή η επικόλληση των επιλεγμένων αρχείων σε αυτήν την τοποθεσία."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Μετονομασία"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Αποτυχία μετονομασίας εγγράφου"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml
index 5dca8e8..ad4fafd 100644
--- a/packages/DocumentsUI/res/values-en-rAU/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Devices"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
     <string name="empty" msgid="7858882803708117596">"No items"</string>
+    <string name="no_results" msgid="6622510343880730446">"No matches in %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
     <string name="share_via" msgid="8966594246261344259">"Share via"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Undo"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Preparing to delete…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">Couldn\'t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
       <item quantity="one">Couldn\'t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Couldn\'t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
       <item quantity="one">Couldn\'t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Touch to view details"</string>
-    <string name="retry" msgid="7564024179122207376">"Retry"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Couldn\'t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+      <item quantity="one">Couldn\'t delete <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Tap to view details"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"These files weren\'t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"These files weren\'t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Copied <xliff:g id="COUNT_0">%1$d</xliff:g> file to clipboard.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Cannot paste the selected files in this location."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"rename"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
index 5dca8e8..ad4fafd 100644
--- a/packages/DocumentsUI/res/values-en-rGB/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Devices"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
     <string name="empty" msgid="7858882803708117596">"No items"</string>
+    <string name="no_results" msgid="6622510343880730446">"No matches in %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
     <string name="share_via" msgid="8966594246261344259">"Share via"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Undo"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Preparing to delete…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">Couldn\'t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
       <item quantity="one">Couldn\'t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Couldn\'t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
       <item quantity="one">Couldn\'t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Touch to view details"</string>
-    <string name="retry" msgid="7564024179122207376">"Retry"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Couldn\'t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+      <item quantity="one">Couldn\'t delete <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Tap to view details"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"These files weren\'t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"These files weren\'t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Copied <xliff:g id="COUNT_0">%1$d</xliff:g> file to clipboard.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Cannot paste the selected files in this location."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"rename"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
index 5dca8e8..ad4fafd 100644
--- a/packages/DocumentsUI/res/values-en-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Devices"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
     <string name="empty" msgid="7858882803708117596">"No items"</string>
+    <string name="no_results" msgid="6622510343880730446">"No matches in %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
     <string name="share_via" msgid="8966594246261344259">"Share via"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Undo"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Preparing to delete…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">Couldn\'t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
       <item quantity="one">Couldn\'t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Couldn\'t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
       <item quantity="one">Couldn\'t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Touch to view details"</string>
-    <string name="retry" msgid="7564024179122207376">"Retry"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Couldn\'t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+      <item quantity="one">Couldn\'t delete <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Tap to view details"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"These files weren\'t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"These files weren\'t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Copied <xliff:g id="COUNT_0">%1$d</xliff:g> file to clipboard.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Cannot paste the selected files in this location."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"rename"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 58090ce..53daa40 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Deshacer"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <item quantity="other">No se pudieron mover <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
       <item quantity="one">No se pudo mover <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Toca el elemento para ver más información."</string>
-    <string name="retry" msgid="7564024179122207376">"Reintentar"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"No se copiaron estos archivos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"No se movieron los siguientes archivos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Se copió <xliff:g id="COUNT_0">%1$d</xliff:g> archivo al portapapeles.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"No se pueden pegar los archivos seleccionados en esta ubicación."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Cambiar nombre"</string>
+    <string name="rename_error" msgid="4203041674883412606">"No se pudo cambiar el nombre del documento"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
index c91a990..d55220c 100644
--- a/packages/DocumentsUI/res/values-es/strings.xml
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Más aplicaciones"</string>
     <string name="empty" msgid="7858882803708117596">"No hay elementos"</string>
+    <string name="no_results" msgid="6622510343880730446">"Sin coincidencias en %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Error al 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 a través de"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Deshacer"</string>
     <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 para eliminar…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">No se han podido copiar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
       <item quantity="one">No se ha podido copiar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
@@ -92,8 +94,13 @@
       <item quantity="other">No se han podido mover <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
       <item quantity="one">No se ha podido mover <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Toca para ver más información"</string>
-    <string name="retry" msgid="7564024179122207376">"Volver a intentar"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">No se han podido eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+      <item quantity="one">No se ha podido eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Toca para ver detalles"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Archivos que no se han copiado: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Archivos que no se han movido: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Se ha copiado <xliff:g id="COUNT_0">%1$d</xliff:g> archivo al portapapeles.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Los archivos seleccionados no se pueden pegar en esta ubicación."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Cambiar nombre"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Error al cambiar el nombre del documento"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index 55d2503..580e203 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Seadmed"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Rohkem rakendusi"</string>
     <string name="empty" msgid="7858882803708117596">"Üksusi ei ole"</string>
+    <string name="no_results" msgid="6622510343880730446">"Otsing %1$s ei andnud vasteid"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Faili ei saa avada"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Mõnda dokumenti ei õnnestu kustutada"</string>
     <string name="share_via" msgid="8966594246261344259">"Jagage teenusega"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Võta tagasi"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopeerimise ettevalmistamine …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Teisaldamise ettevalmistamine …"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Kustutamise ettevalmistamine …"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei saanud kopeerida</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei saanud kopeerida</item>
@@ -92,8 +94,13 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei saanud teisaldada</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei saanud teisaldada</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Puudutage üksikasjade vaatamiseks"</string>
-    <string name="retry" msgid="7564024179122207376">"Proovi uuesti"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei õnnestunud kustutada</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei õnnestunud kustutada</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Puudutage üksikasjade vaatamiseks"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Neid faile ei kopeeritud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Neid faile ei teisaldatud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fail kopeeriti lõikelauale.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Valitud faile ei saa sellesse asukohta kleepida."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Nimeta ümber"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Dokumendi ümbernimetamine ebaõnnestus"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml
index 7ad1dbc..2dab78b 100644
--- a/packages/DocumentsUI/res/values-eu-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Gailuak"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"Ezin da fitxategia ireki"</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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Desegin"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Xehetasunak ikusteko, ukitu hau."</string>
-    <string name="retry" msgid="7564024179122207376">"Saiatu berriro"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ez dira kopiatu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Ez dira mugitu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi kopiatu da arbelean.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Ezin dira itsatsi hautatutako fitxategiak kokapen honetan."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Aldatu izena"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Ezin izan zaio aldatu izena dokumentuari"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index 1989c62..2cfea03 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"دستگاه‌ها"</string>
     <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="1339885974067891667">"فایل باز نمی‌شود"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"برخی از اسناد حذف نمی‌شوند"</string>
     <string name="share_via" msgid="8966594246261344259">"اشتراک‌گذاری از طریق"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"لغو"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"در حال آماده‌سازی برای کپی..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"درحال آماده‌سازی برای انتقال…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"درحال آماده‌سازی برای حذف…‏"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"برای مشاهده جزئیات لمس کنید"</string>
-    <string name="retry" msgid="7564024179122207376">"امتحان مجدد"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"این فایل‌ها کپی نشدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"این فایل‌ها منتقل نشدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل در بریده‌دان کپی شد.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"نمی‌توان فایل‌های انتخابی را در این مکان جای‌گذاری کرد."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"تغییر نام"</string>
+    <string name="rename_error" msgid="4203041674883412606">"نام سند تغییر نکرد"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index 9228634..b4ed0fd 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Laitteet"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"Tiedostoa ei voi avata"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Joitakin asiakirjoja ei voi poistaa"</string>
     <string name="share_via" msgid="8966594246261344259">"Jaa sovelluksessa"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Kumoa"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Lue lisätietoja koskettamalla"</string>
-    <string name="retry" msgid="7564024179122207376">"Yritä uudelleen"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Seuraavia tiedostoja ei kopioitu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Näitä tiedostoja ei siirretty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto kopioitiin leikepöydälle.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Valittuja tiedostoja ei voi liittää tähän sijaintiin."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Nimeä uudelleen"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Dokumentin nimen muuttaminen epäonnistui."</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index ec81e67..5bbc884 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Appareils"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Annuler"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Touchez ici pour afficher les détails"</string>
-    <string name="retry" msgid="7564024179122207376">"Réessayer"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ces fichiers ne ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Ces fichiers n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fichiers ont été copiés dans le presse-papiers.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Impossible de coller les fichiers sélectionnés à cet endroit."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Renommer"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Impossible de renommer le document"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index 3d7ab32..2e06b74 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Appareils"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Annuler"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Appuyez pour en savoir plus."</string>
-    <string name="retry" msgid="7564024179122207376">"Réessayer"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"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="7151140279020481180">"Les fichiers suivants n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fichiers ont bien été copiés dans le Presse-papiers.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Impossible de coller les fichiers sélectionnés à cet endroit."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Renommer"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Échec du changement de nom du document."</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index db98006..5997e3d 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Desfacer"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Toca para ver detalles"</string>
-    <string name="retry" msgid="7564024179122207376">"Tentar de novo"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Non se copiaron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Non se moveron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Copiouse <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro no portapapeis.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Non se poden pegar os ficheiros seleccionados nesta localización."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Cambiar nome"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Non se puido cambiar o nome do documento"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-gu-rIN/strings.xml b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
index 9f5eba0..f013e0f 100644
--- a/packages/DocumentsUI/res/values-gu-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"ઉપકરણો"</string>
     <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="1339885974067891667">"ફાઇલ ખોલી શકાતી નથી"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"કેટલાક દસ્તાવેજો કાઢી નાખવામાં અસમર્થ"</string>
     <string name="share_via" msgid="8966594246261344259">"આના દ્વારા શેર કરો"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"પૂર્વવત્ કરો"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"કૉપિ માટે તૈયારી કરી રહ્યું છે…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ખસેડવા માટે તૈયાર કરી રહ્યું છે…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"કાઢી નાખવાની તૈયારી કરી રહ્યાં છે…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"વિગતો જોવા માટે ટચ કરો"</string>
-    <string name="retry" msgid="7564024179122207376">"ફરી પ્રયાસ કરો"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"આ ફાઇલો કૉપિ કરી નહોતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"આ ફાઇલો ખસેડી નહોતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other">ક્લિપબોર્ડ પર <xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો કૉપિ કરી.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"આ સ્થાનમાં પસંદ કરેલ ફાઇલો પેસ્ટ કરી શકાતી નથી."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"નામ બદલો"</string>
+    <string name="rename_error" msgid="4203041674883412606">"દસ્તાવેજનું નામ બદલવામાં નિષ્ફળ થયાં"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index d146145..008995e 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"डिवाइस"</string>
     <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="1339885974067891667">"फ़ाइल नहीं खोली जा सकती"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"कुछ दस्तावेज़ों को हटाने में अक्षम"</string>
     <string name="share_via" msgid="8966594246261344259">"इसके द्वारा साझा करें"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"वापस लाएं"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"कॉपी करने की तैयारी हो रही है…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ले जाने की तैयारी हो रही है…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"हटाने के लिए तैयार हो रहा है…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"विवरण देखने के लिए स्पर्श करें"</string>
-    <string name="retry" msgid="7564024179122207376">"पुन: प्रयास करें"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"इन फ़ाइलों की कॉपी नहीं बनाई गई: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ये फ़ाइलें नहीं ले जाई गईं: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other">क्‍लिपबोर्ड पर <xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों की कॉपी बनाई गई.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"चयनित फ़ाइलों को इस स्‍थान में नहीं चिपकाया जा सकता."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"नाम बदलें"</string>
+    <string name="rename_error" msgid="4203041674883412606">"दस्‍तावेज़ का नाम बदलना विफल रहा"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index 5884d6f..d6110a5 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -63,6 +63,7 @@
     <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">"%1$s ne sadrži podudaranja"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Datoteku nije moguće otvoriti"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće izbrisati neke dokumente"</string>
     <string name="share_via" msgid="8966594246261344259">"Dijeli putem"</string>
@@ -87,6 +88,7 @@
     <string name="undo" msgid="7905788502491742328">"Poništi"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Priprema za kopiranje…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Priprema za premještanje…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Priprema za brisanje…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije kopirana</item>
       <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nisu kopirane</item>
@@ -97,8 +99,14 @@
       <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nisu premještene</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije premješteno</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Dodirnite da biste vidjeli pojedinosti"</string>
-    <string name="retry" msgid="7564024179122207376">"Pokušaj ponovo"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije izbrisana</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nisu izbrisane</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije izbrisano</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Dodirnite da biste vidjeli pojedinosti"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ove datoteke nisu kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Ove datoteke nisu premještene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -107,4 +115,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka kopirano je u međuspremnik.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Nije moguće zalijepiti odabrane datoteke na ovu lokaciju."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Promijeni naziv"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Naziv dokumenta nije promijenjen"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index 95b45ba..139b834 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Eszközök"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"További alkalmazások"</string>
     <string name="empty" msgid="7858882803708117596">"Nincsenek elemek"</string>
+    <string name="no_results" msgid="6622510343880730446">"Nincs találat itt: %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"A fájlt nem lehet megnyitni"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Néhány dokumentumot nem lehet törölni"</string>
     <string name="share_via" msgid="8966594246261344259">"Megosztás itt:"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Visszavonás"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Felkészülés a másolásra…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Áthelyezés előkészítése…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Törlés előkészítése…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájlt nem sikerült átmásolni</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájlt nem sikerült átmásolni</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Nem sikerült áthelyezni <xliff:g id="COUNT_1">%1$d</xliff:g> fájlt</item>
       <item quantity="one">Nem sikerült áthelyezni <xliff:g id="COUNT_0">%1$d</xliff:g> fájlt</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Érintse meg a részletek megtekintéséhez"</string>
-    <string name="retry" msgid="7564024179122207376">"Újra"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájlt nem sikerült törölni</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájlt nem sikerült törölni</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Koppintson rá a részletek megtekintéséhez"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"A következő fájlokat nem sikerült átmásolni: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"A következő fájlok nem lettek áthelyezve: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> fájl vágólapra másolva.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"A kijelölt fájlokat nem lehet beilleszteni erre a helyre."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Átnevezés"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Nem sikerült átnevezni a dokumentumot"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index 7be66d3..8fc7e09 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Սարքեր"</string>
     <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="1339885974067891667">"Հնարավոր չէ բացել ֆայլը"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Անհնար է ջնջել որոշ փաստաթղթեր"</string>
     <string name="share_via" msgid="8966594246261344259">"Տարածել"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Հետարկել"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Պատճենման նախապատրաստում…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Տեղափոխման նախապատրաստում…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Պատրաստվում է ջնջել…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"Հպեք՝ մանրամասները դիտելու համար"</string>
-    <string name="retry" msgid="7564024179122207376">"Կրկնել"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Հետևյալ ֆայլերը չեն պատճենվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Հետևյալ ֆայլերը չեն տեղափոխվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ պատճենվեց սեղմատախտակին:</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Հնարավոր չէ տեղադրել ընտրված ֆայլերը այս տեղադրությունում:"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Վերանվանել"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Չհաջողվեց վերանվանել փաստաթուղթը"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
index 29d66c0..0cb438a 100644
--- a/packages/DocumentsUI/res/values-in/strings.xml
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Perangkat"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Aplikasi lain"</string>
     <string name="empty" msgid="7858882803708117596">"Tidak ada item"</string>
+    <string name="no_results" msgid="6622510343880730446">"Tidak ada kecocokan dalam %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Tidak dapat membuka file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat menghapus beberapa dokumen"</string>
     <string name="share_via" msgid="8966594246261344259">"Bagikan melalui"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Urungkan"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Menyiapkan salinan..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Menyiapkan pemindahan…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Bersiap menghapus…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">Tidak dapat menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
       <item quantity="one">Tidak dapat menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Tidak dapat memindahkan <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
       <item quantity="one">Tidak dapat memindahkan <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Sentuh untuk melihat detail"</string>
-    <string name="retry" msgid="7564024179122207376">"Coba lagi"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Tidak dapat menghapus <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+      <item quantity="one">Tidak dapat menghapus <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Ketuk untuk melihat detail"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Semua file ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Semua file ini tidak dipindahkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> file disalin ke papan klip.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Tidak dapat menempel file yang dipilih di lokasi ini."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Ganti nama"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Gagal mengganti nama dokumen"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index 76dbe32..efd3f7b 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Tæki"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"Ekki er hægt að opna skrána"</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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Afturkalla"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="one">Ekki var hægt að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
       <item quantity="other">Ekki var hægt að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrár</item>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Snertu til að skoða nánari upplýsingar"</string>
-    <string name="retry" msgid="7564024179122207376">"Reyna aftur"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Þessar skrár voru ekki afritaðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Þessar skrár voru ekki færðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skrár afritaðar á klippiborð.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Ekki er hægt að vista valdar skrár á þessum stað."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Endurnefna"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Ekki tókst að endurnefna skjalið"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
index 2e74550..1b7506d 100644
--- a/packages/DocumentsUI/res/values-it/strings.xml
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Dispositivi"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Altre app"</string>
     <string name="empty" msgid="7858882803708117596">"Nessun elemento"</string>
+    <string name="no_results" msgid="6622510343880730446">"Nessuna corrispondenza in %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Impossibile aprire il file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Impossibile eliminare alcuni documenti"</string>
     <string name="share_via" msgid="8966594246261344259">"Condividi via"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Annulla"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparazione alla copia…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparazione dello spostamento…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Preparazione eliminazione…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">Impossibile copiare <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
       <item quantity="one">Impossibile copiare <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Impossibile spostare <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
       <item quantity="one">Impossibile spostare <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Tocca per visualizzare i dettagli"</string>
-    <string name="retry" msgid="7564024179122207376">"Riprova"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Impossibile eliminare <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+      <item quantity="one">Impossibile eliminare <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Tocca per vedere i dettagli"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"I seguenti file non sono stati copiati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"I seguenti file non sono stati spostati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> file copiato negli appunti.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Impossibile incollare i file selezionati in questa posizione."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Rinomina"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Ridenominazione documento non riuscita"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index ed0a6a4..ef966f4 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"מכשירים"</string>
     <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="1339885974067891667">"לא ניתן לפתוח את הקובץ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"לא ניתן למחוק חלק מהמסמכים"</string>
     <string name="share_via" msgid="8966594246261344259">"שתף באמצעות"</string>
@@ -90,6 +91,7 @@
     <string name="undo" msgid="7905788502491742328">"בטל"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"מתכונן להעתקה..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"מתכונן להעברה…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"מתכונן למחיקה…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -102,8 +104,15 @@
       <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="4483108577842961665">"גע כדי להציג את הפרטים"</string>
-    <string name="retry" msgid="7564024179122207376">"נסה שוב"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"הקבצים הבאים לא הועתקו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"הקבצים הבאים לא הועברו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -113,4 +122,6 @@
       <item quantity="one">קובץ <xliff:g id="COUNT_0">%1$d</xliff:g> הועתק אל הלוח.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"לא ניתן להדביק את הקבצים הנבחרים במיקום הזה."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"שנה שם"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ניסיון שינוי שם המסמך נכשל"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index a954927..932e7fc 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"端末"</string>
     <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="1339885974067891667">"ファイルを開けません"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"一部のドキュメントを削除できません"</string>
     <string name="share_via" msgid="8966594246261344259">"共有ツール"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"元に戻す"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"コピーの準備をしています…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"移動の準備をしています…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"削除の準備をしています…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"タップして詳細をご覧ください"</string>
-    <string name="retry" msgid="7564024179122207376">"再試行"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ファイル(<xliff:g id="LIST">%1$s</xliff:g>)をコピーできませんでした"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ファイル(<xliff:g id="LIST">%1$s</xliff:g>)を移動できませんでした"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>件のファイルをクリップボードにコピーしました。</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"選択したファイルをこの場所に貼り付けることはできません。"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"名前を変更"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ドキュメントの名前を変更できませんでした"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index ef91fab..370e228 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"მოწყობილობები"</string>
     <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="1339885974067891667">"ფაილის გახსნა ვერ ხერხდება"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ზოგიერთი დოკუმენტის წაშლა ვერ ხერხდება"</string>
     <string name="share_via" msgid="8966594246261344259">"გაზიარება:"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"დაბრუნება"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"მომზადება კოპირებისთვის…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"გადაადგილება მზადდება..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"მზადდება წასაშლელად…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"შეეხეთ მონაცემების სანახავად."</string>
-    <string name="retry" msgid="7564024179122207376">"ხელახლა ცდა"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ეს ფაილები არ იყო გადაწერილი: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ეს ფაილები ვერ გადაადგილდა: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">მოხდა <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილის გაცვლის ბუფერში კოპირება.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ამ მდებარეობაში შერჩეული ფაილების ჩასმა შეუძლებელია."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"გადარქმევა"</string>
+    <string name="rename_error" msgid="4203041674883412606">"დოკუმენტის გადარქმევა ვერ მოხერხდა"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
index 09d7e37..bea34c7 100644
--- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
+++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Құрылғылар"</string>
     <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="1339885974067891667">"Файлды аша алмады"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Кейбір құжаттарды жою мүмкін болмады"</string>
     <string name="share_via" msgid="8966594246261344259">"Бөлісу"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Кері қайтару"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Көшіруге дайындау…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Тасымалдауға дайындалуда..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Жоюға дайындалуда…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"Толығырақ мәліметті көру үшін түртіңіз"</string>
-    <string name="retry" msgid="7564024179122207376">"Қайталау"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Мына файлдар көшірілген жоқ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Мына файлдар тасымалданған жоқ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Аралық сақтағышқа <xliff:g id="COUNT_0">%1$d</xliff:g> файл көшірілді.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Таңдалған файлдарды бұл орынға қою мүмкін емес."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Атын өзгерту"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Құжат қайта аталмады"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index f95594b6..31b8816 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"ឧបករណ៍"</string>
     <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="1339885974067891667">"មិន​អាច​បើក​ឯកសារ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"មិន​អាច​លុប​ឯកសារ​មួយ​ចំនួន"</string>
     <string name="share_via" msgid="8966594246261344259">"ចែករំលែក​តាម"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"មិនធ្វើវិញ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"កំពុងរៀបចំចម្លង…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"កំពុងរៀបចំផ្លាស់ទី…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"កំពុងរៀបចំលុប…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"ប៉ះ ដើម្បីមើលព័ត៌មានលម្អិត"</string>
-    <string name="retry" msgid="7564024179122207376">"ព្យាយាមម្ដងទៀត"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ឯកសារទាំងនេះមិនបានចម្លងទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ឯកសារទាំងនេះមិនអាចផ្លាស់ទីបានទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">បានចម្លងឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g> ទៅតម្បៀតខ្ទាស់។</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"មិនអាចបិទភ្ជាប់ឯកសារដែលបានជ្រើសនៅក្នុងទីតាំងនេះបានទេ។"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"ប្ដូរឈ្មោះ"</string>
+    <string name="rename_error" msgid="4203041674883412606">"បានបរាជ័យក្នុងការប្តូរឈ្មោះឯកសារ"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
index 5da5cd0..ab4e90b 100644
--- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"ಸಾಧನಗಳು"</string>
     <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="1339885974067891667">"ಫೈಲ್ ತೆರೆಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ಕೆಲವು ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
     <string name="share_via" msgid="8966594246261344259">"ಈ ಮೂಲಕ ಹಂಚಿಕೊಳ್ಳಿ"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"ನಕಲಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"ಸರಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"ಅಳಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"ವಿವರಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಸ್ಪರ್ಶಿಸಿ"</string>
-    <string name="retry" msgid="7564024179122207376">"ಮರುಪ್ರಯತ್ನಿಸು"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ಈ ಫೈಲ್‌ಗಳನ್ನು ನಕಲು ಮಾಡಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ಈ ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other">ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗಿದೆ.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ಈ ಸ್ಥಳದಲ್ಲಿ ಆಯ್ಕೆಮಾಡಿದ ಫೈಲ್‌ಗಳನ್ನು ಅಂಟಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"ಮರುಹೆಸರಿಸು"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ಡಾಕ್ಯುಮೆಂಟ್ ಮರುಹೆಸರಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index 4074841..9bb596d 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"기기"</string>
     <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="1339885974067891667">"파일을 열 수 없음"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"일부 문서를 삭제할 수 없음"</string>
     <string name="share_via" msgid="8966594246261344259">"공유 방법"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"실행취소"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"사본 준비 중…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"이동 준비 중…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"삭제 준비 중..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"세부정보를 보려면 터치하세요."</string>
-    <string name="retry" msgid="7564024179122207376">"다시 시도"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"다음 파일이 복사되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"다음 파일이 이동되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 클립보드에 복사함</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"선택한 파일을 이 위치에 붙여넣을 수 없습니다."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"이름 바꾸기"</string>
+    <string name="rename_error" msgid="4203041674883412606">"문서 이름을 변경하지 못했습니다."</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index 6172c77..c29fc45 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Түзмөктөр"</string>
     <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="1339885974067891667">"Файл ачылбады"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Кээ бир документтерди өчүрүү кыйрады"</string>
     <string name="share_via" msgid="8966594246261344259">"Кийинки аркылуу бөлүшүү:"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Артка кайтаруу"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Көчүрүүгө даярдалууда…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Жылдырууга даярдалууда…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Жок кылууга даярдалууда…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"Чоо-жайын билүү үчүн тийип коюңуз"</string>
-    <string name="retry" msgid="7564024179122207376">"Дагы аракет кылуу"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Төмөнкү файлдар көчүрүлгөн жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Төмөнкү файлдар жылдырылган жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файл буферге көчүрүлдү.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Тандалган файлдарды бул жерге чаптоого мүмкүн эмес."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Аталышын өзгөртүү"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Документтин аталышы өзгөртүлбөй калды"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index baa7e25..223adae 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"ອຸປະກອນ"</string>
     <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="1339885974067891667">"ບໍ່ສາມດາເປີດໄຟລ໌ໄດ້"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ບໍ່ສາມາດລຶບບາງເອກະສານໄດ້"</string>
     <string name="share_via" msgid="8966594246261344259">"ແບ່ງປັນຜ່ານ"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"ບໍ່​ເຮັດ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"ກຳ​ລັງ​ກຽມ​ອັດ​ສຳ​ເນົາ…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ກຳ​ລັງ​ກະ​ກຽມ​ຍ້າຍ…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"ກຳລັງກະກຽມລຶບ…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"ສຳ​ພັດເພື່ອເບິ່ງລາຍລະອຽດ"</string>
-    <string name="retry" msgid="7564024179122207376">"ລອງໃໝ່"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ໄຟ​ລ໌​ເຫຼົ່າ​ນີ້​ບໍ່​ຖື​ກ​ອັດ​ສຳ​ເນົາ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ໄຟ​ລ໌​ເຫຼົ່າ​ນີ້​ບໍ່​ຖືກ​ຍ້າຍ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">ອັດ​ສຳ​ເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟ​ລ໌​ໃສ່​ຄ​ລິບບອດ​ແລ້ວ.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ບໍ່​ສາ​ມາດ​ແປະ​ໄຟ​ລ໌​ເລືອກ​ໄວ້​ຢູ່​ໃນ​ທີ່​ຕັ້ງ​ນີ້​ໄດ້."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"ປ່ຽນຊື່"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ປ່ຽນຊື່ເອກະສານບໍ່ສຳເລັດ"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index dadd006..8993ffa 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Įrenginiai"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Daugiau programų"</string>
     <string name="empty" msgid="7858882803708117596">"Nėra elementų"</string>
+    <string name="no_results" msgid="6622510343880730446">"Nėra jokių atitikčių pagal %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Nepavyksta atidaryti failo"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nepavyko ištrinti kai kurių dokumentų"</string>
     <string name="share_via" msgid="8966594246261344259">"Bendrinti naudojant"</string>
@@ -90,6 +91,7 @@
     <string name="undo" msgid="7905788502491742328">"Anuliuoti"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Ruošiamasi kopijuoti…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Ruošiamasi perkelti…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Ruošiama ištrinti…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="one">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
       <item quantity="few">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
@@ -102,8 +104,15 @@
       <item quantity="many">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
       <item quantity="other">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Palieskite, kad peržiūr. išsamią informaciją"</string>
-    <string name="retry" msgid="7564024179122207376">"Bandyti dar kartą"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="one">Nepavyko ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
+      <item quantity="few">Nepavyko ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
+      <item quantity="many">Nepavyko ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
+      <item quantity="other">Nepavyko ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Palieskite, kad peržiūrėtumėte informaciją"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Šie failai nenukopijuoti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Šie failai nebuvo perkelti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -113,4 +122,6 @@
       <item quantity="other">Nukopijuota <xliff:g id="COUNT_1">%1$d</xliff:g> failų į iškarpinę.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Nepavyko įklijuoti pasirinktų failų šioje vietoje."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Pervardyti"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Nepavyko pervardyti dokumento"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index 4e0d519..6544834 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Ierīces"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -87,6 +88,7 @@
     <string name="undo" msgid="7905788502491742328">"Atsaukt"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -97,8 +99,14 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Pieskarieties, lai skatītu informāciju"</string>
-    <string name="retry" msgid="7564024179122207376">"Mēģināt vēlreiz"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Netika nokopēti šādi faili: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Šie faili netika pārvietoti: <xliff:g id="LIST">%1$s</xliff:g>."</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -107,4 +115,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili tika kopēti starpliktuvē.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Atlasītos failus šeit nevar ielīmēt."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Pārdēvēt"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Neizdevās pārdēvēt dokumentu"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
index 51cb774..ec2ab82 100644
--- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml
+++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Уреди"</string>
     <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="1339885974067891667">"Датотеката не се отвора"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Некои документи не може да се избришат"</string>
     <string name="share_via" msgid="8966594246261344259">"Сподели преку"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Врати"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Се подготвува за копирање…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Се подготвува за преместување…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Се подготвува за бришење…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"Допрете за да ги погледнете деталите"</string>
-    <string name="retry" msgid="7564024179122207376">"Обидете се повторно"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Датотекиве не се ископирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Овие датотеки не се преместија: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other">Копирани се <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки на таблата со исечоци.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Не може да ги залепи избраните датотеки на локацијава."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Преименувај"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Не успеа да се преименува документот"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
index 1de31ce..6e23f6c 100644
--- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"ഉപകരണങ്ങൾ"</string>
     <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="1339885974067891667">"ഫയൽ തുറക്കാനായില്ല"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ചില പ്രമാണങ്ങൾ ഇല്ലാതാക്കാനായില്ല"</string>
     <string name="share_via" msgid="8966594246261344259">"ഇതുവഴി പങ്കിടുക"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"പഴയപടിയാക്കുക"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"പകർപ്പിനായി തയ്യാറെടുക്കുന്നു…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"നീക്കാനൊരുങ്ങുന്നു…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"ഇല്ലാതാക്കാൻ തയ്യാറെടുക്കുന്നു..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"വിശദാംശങ്ങൾ കാണാൻ സ്‌പർശിക്കുക"</string>
-    <string name="retry" msgid="7564024179122207376">"വീണ്ടും ശ്രമിക്കുക"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ഈ ഫയലുകൾ പകർത്താനായില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ഈ ഫയലുകളെ നീക്കിയില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ ക്ലിപ്പ്‌ബോർഡിലേക്ക് പകർത്തി.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"തിരഞ്ഞെടുത്ത ഫയലുകൾ ഈ ലൊക്കേഷനിൽ ഒട്ടിക്കാനാകുന്നില്ല."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"പേരുമാറ്റുക"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ഡോക്യുമെന്റിന്റെ പേരുമാറ്റുന്നത് പരാജയപ്പെട്ടു"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
index d0e43f4..137d5eb 100644
--- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Төхөөрөмжүүд"</string>
     <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="1339885974067891667">"Файлыг нээх боломжгүй"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Зарим документуудыг устгах боломжгүй"</string>
     <string name="share_via" msgid="8966594246261344259">"Дараахаар дамжуулан хуваалцах"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Буцаах"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Хуулбарлахад бэлтгэж байна..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Зөөвөрлөхөд бэлтгэж байна..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Устгах гэж байна..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"Дэлгэрэнгүй мэдээллийг үзэхийн тулд хүрнэ үү."</string>
-    <string name="retry" msgid="7564024179122207376">"Дахин оролдох"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Дараах файлуудыг хуулаагүй: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Эдгээр файлыг зөөвөрлөөгүй байна: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> материалыг түр санах ой руу хуулсан.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Энэ байршилд сонгосон файлыг байршуулах боломжгүй байна."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Нэр өөрчлөх"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Баримт бичгийн нэрийн өөрчилж чадсангүй"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
index e359e1e..babb452 100644
--- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"डिव्हाइसेस"</string>
     <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="1339885974067891667">"फाईल उघडू शकत नाही"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"काही दस्‍तऐवज हटविण्‍यात अक्षम"</string>
     <string name="share_via" msgid="8966594246261344259">"द्वारे सामायिक करा"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"पूर्ववत करा"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"कॉपी करण्‍यासाठी तयार करीत आहे…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"हलविण्‍यास तयार होत आहे…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"हटविण्‍यासाठी तयार करीत आहे..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"तपशील पाहण्यासाठी स्पर्श करा"</string>
-    <string name="retry" msgid="7564024179122207376">"पुन्हा प्रयत्न करा"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"या फायली कॉपी झाल्या नाहीत: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"या फायली हलविल्या नव्हत्या: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other">क्लिपबोर्डवर <xliff:g id="COUNT_1">%1$d</xliff:g> फायली कॉपी केल्या.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"या स्थानामध्‍ये निवडलेल्‍या फायली पेस्ट करू शकत नाही."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"पुनर्नामित करा"</string>
+    <string name="rename_error" msgid="4203041674883412606">"दस्तऐवज पुनर्नामित करण्‍यात अयशस्वी झाले"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index ea88ef6..5d0dbdf 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Peranti"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Buat asal"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Sentuh untuk melihat butiran"</string>
-    <string name="retry" msgid="7564024179122207376">"Cuba semula"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Fail ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Fail ini tidak dialihkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fail disalin ke papan keratan.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Tidak boleh menampalkan fail yang dipilih dalam lokasi ini."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Namakan semula"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Gagal menamakan semula dokumen"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index 4c8fb49..0621d44 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"စက်ပစ္စည်းများ"</string>
     <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="1339885974067891667">"ဖိုင်အား ဖွင့်မရပါ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"တချို့ စာရွက်စာတန်းများ မဖျက်စီးနိုင်ပါ"</string>
     <string name="share_via" msgid="8966594246261344259">"မှ ဝေမျှပါ"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"ပြန်ဖျက်ရန်"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"မိတ္တူကူးရန်ပြင်ဆင်နေ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"ရွှေ့ရန် ပြင်ဆင်နေသည်…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"ဖျက်ရန်အတွက် ပြင်ဆင်နေသည်..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"အသေးစိတ် ကြည့်ရန် ထိပါ။"</string>
-    <string name="retry" msgid="7564024179122207376">"ထပ်စမ်းရန်"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ဤဖိုင်များ ကော်ပီကူးမထားပါ- <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ဤဖိုင်များကို မရွှေ့ခဲ့ပါ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"> ဖိုင် <xliff:g id="COUNT_0">%1$d</xliff:g> ဖိုင်ကိုအချက်အလက်သိမ်းတဲ့နေရာသို့ ကူးယူပါ။</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ဤနေရာတွင် ရွေးချယ်ထားသည့် ဖိုင်များကို ကူးထည့်၍မရပါ။"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"အမည်ပြောင်းရန်"</string>
+    <string name="rename_error" msgid="4203041674883412606">"စာရွက်စာတမ်းကို အမည်ပြောင်းခြင်း မအောင်မြင်ပါ"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index 01dda74..c4a8e2a 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Enheter"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Angre"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Trykk for å se detaljer"</string>
-    <string name="retry" msgid="7564024179122207376">"Prøv på nytt"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Disse filene ble ikke kopiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Disse filene ble ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Kopierte <xliff:g id="COUNT_0">%1$d</xliff:g> fil til utklippstavlen.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Kan ikke lime inn de valgte filene her."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Gi nytt navn"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Kunne ikke gi dokumentet nytt navn"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index cd809af..a40edc7 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"उपकरणहरू"</string>
     <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="1339885974067891667">"फाइल खोल्न सक्दैन"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"केही कागजातहरू मेट्न असमर्थ छ"</string>
     <string name="share_via" msgid="8966594246261344259">"माध्यमबाट साझेदारी गर्नुहोस्"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"अनडू गर्नुहोस्"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"प्रतिलिपिको लागि तयारी गर्दै ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"सार्नको लागि तयारी गर्दै ..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"मेटाउन तयारी गर्दै..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"विवरणहरू हेर्न छुनुहोस्"</string>
-    <string name="retry" msgid="7564024179122207376">"पुनःप्रयास गर्नुहोस्"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"यी फाइलहरू प्रतिलिपि गरिएको थिएनः <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"यी फाइलहरू सारिएनन्: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"> क्लिपबोर्डमा <xliff:g id="COUNT_0">%1$d</xliff:g> फाइलहरूका प्रतिलिपि बनाइए।</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"यो स्थानमा चयन गरिएका फाइलहरू टाँस्न सकिँदैन।"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"पुन: नामाकरण गर्नुहोस्"</string>
+    <string name="rename_error" msgid="4203041674883412606">"कागजात पुन: नामाकरण गर्न असफल भयो"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index 5948167..eecc871 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Apparaten"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Meer apps"</string>
     <string name="empty" msgid="7858882803708117596">"Geen items"</string>
+    <string name="no_results" msgid="6622510343880730446">"Geen overeenkomsten in %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Kan bestand niet openen"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Kan bepaalde documenten niet verwijderen"</string>
     <string name="share_via" msgid="8966594246261344259">"Delen via"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Ongedaan maken"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopiëren voorbereiden…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Verplaatsen voorbereiden…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Verwijderen voorbereiden…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> bestanden niet kopiëren</item>
       <item quantity="one">Kan <xliff:g id="COUNT_0">%1$d</xliff:g> bestand niet kopiëren</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> bestanden niet verplaatsen</item>
       <item quantity="one">Kan <xliff:g id="COUNT_0">%1$d</xliff:g> bestand niet verplaatsen</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Tik om details weer te geven"</string>
-    <string name="retry" msgid="7564024179122207376">"Opnieuw proberen"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> bestanden niet verwijderen</item>
+      <item quantity="one">Kan <xliff:g id="COUNT_0">%1$d</xliff:g> bestand niet verwijderen</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Tik om details te bekijken"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Deze bestanden zijn niet gekopieerd: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Deze bestanden zijn niet verplaatst: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand gekopieerd naar klembord.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Kan de geselecteerde bestanden niet plakken op deze locatie."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Naam wijzigen"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Kan naam van document niet wijzigen"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
index dd081ab..075ca4d 100644
--- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"ਡਿਵਾਈਸਾਂ"</string>
     <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="1339885974067891667">"ਫਾਈਲ ਨਹੀਂ ਖੋਲ੍ਹ ਸਕਦਾ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ਕੁਝ ਦਸਤਾਵੇਜ਼ ਮਿਟਾਉਣ ਵਿੱਚ ਅਸਮਰੱਥ"</string>
     <string name="share_via" msgid="8966594246261344259">"ਇਸ ਰਾਹੀਂ ਸ਼ੇਅਰ ਕਰੋ"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"ਪਹਿਲਾਂ ਵਰਗਾ ਕਰੋ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"ਕਾਪੀ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ਮੂਵ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"ਮਿਟਾਉਣ ਦੀ ਤਿਆਰੀ ਹੋ ਰਹੀ ਹੈ…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"ਵੇਰਵੇ ਵੇਖਣ ਲਈ ਸਪਰਸ਼ ਕਰੋ"</string>
-    <string name="retry" msgid="7564024179122207376">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਨਹੀਂ ਬਣਾਈ ਗਈ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਨਹੀਂ ਕੀਤਾ ਗਿਆ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other">ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਬਣਾਈ ਗਈ।</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ਇਸ ਸਥਾਨ ਵਿੱਚ ਚੁਣੀਆਂ ਗਈਆਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਪੇਸਟ ਨਹੀਂ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"ਮੁੜ-ਨਾਮਕਰਨ ਕਰੋ"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ਦਸਤਾਵੇਜ਼ ਦਾ ਮੁੜ-ਨਾਮਕਰਨ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 3fd3266..3c86b7b 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Urządzenia"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -90,6 +91,7 @@
     <string name="undo" msgid="7905788502491742328">"Cofnij"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="few">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
       <item quantity="many">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
@@ -102,8 +104,15 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Kliknij, by zobaczyć szczegóły"</string>
-    <string name="retry" msgid="7564024179122207376">"Ponów"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Te pliki nie zostały skopiowane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Te pliki nie zostały przeniesione: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -113,4 +122,6 @@
       <item quantity="one">Skopiowano <xliff:g id="COUNT_0">%1$d</xliff:g> plik do schowka.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Nie można wkleić wybranych plików w tej lokalizacji."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Zmień nazwę"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Nie udało się zmienić nazwy dokumentu"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
index dce7cc0..186569c 100644
--- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Desfazer"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Toque para ver detalhes"</string>
-    <string name="retry" msgid="7564024179122207376">"Repetir"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Não é possível colar os arquivos selecionados neste local."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Renomear"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index 02cd2dd..961330e 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Anular"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Toque para ver detalhes"</string>
-    <string name="retry" msgid="7564024179122207376">"Tentar novamente"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Os seguintes ficheiros não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Os seguintes ficheiros não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Copiou <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro para a área de transferência.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Não é possível colar os ficheiros selecionados nesta localização."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Mudar o nome"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Falha ao mudar o nome do documento"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index dce7cc0..186569c 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Desfazer"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Toque para ver detalhes"</string>
-    <string name="retry" msgid="7564024179122207376">"Repetir"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Não é possível colar os arquivos selecionados neste local."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Renomear"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 5d32285..4ba7618 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Dispozitive"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -87,6 +88,7 @@
     <string name="undo" msgid="7905788502491742328">"Anulați"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -97,8 +99,14 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Atingeți pentru a afișa detaliile"</string>
-    <string name="retry" msgid="7564024179122207376">"Reîncercați"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> fișiere nu au fost șterse</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere nu au fost șterse</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fișier nu a fost șters</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Atingeți pentru a vedea detaliile"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Aceste fișiere nu au fost copiate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Aceste fișiere nu au fost mutate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -107,4 +115,6 @@
       <item quantity="one">A fost copiat <xliff:g id="COUNT_0">%1$d</xliff:g> fișier în clipboard.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Fișierele selectate nu au putut fi inserate în această locație."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Redenumiți"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Documentul nu a putut fi redenumit"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index e68c137..924473a 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Устройства"</string>
     <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="1339885974067891667">"Не удалось открыть файл"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Не удалось удалить некоторые документы"</string>
     <string name="share_via" msgid="8966594246261344259">"Поделиться"</string>
@@ -90,6 +91,7 @@
     <string name="undo" msgid="7905788502491742328">"Отменить"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Подготовка к копированию…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Подготовка…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Подготовка к удалению…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -102,8 +104,15 @@
       <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="4483108577842961665">"Нажмите, чтобы узнать подробности."</string>
-    <string name="retry" msgid="7564024179122207376">"Повторить"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Не удалось скопировать эти файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Эти файлы не были перемещены: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -113,4 +122,6 @@
       <item quantity="other">Скопированы <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Не удается вставить сюда выбранные файлы"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Переименовать"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Не удалось переименовать документ"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml
index 0f40df9..382bed1 100644
--- a/packages/DocumentsUI/res/values-si-rLK/strings.xml
+++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"උපාංග"</string>
     <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="1339885974067891667">"ගොනුව විවෘත කළ නොහැක"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"සමහර ලේඛන මැකීමට නොහැකි විය"</string>
     <string name="share_via" msgid="8966594246261344259">"හරහා බෙදාගන්න"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"අස් කරන්න"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"පිටපතක් සඳහා සූදානම් කරමින්..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"ගෙන යාම සඳහා පිළියෙළ කරමින් ..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"මැකීම සඳහා සූදානම් කරමින්..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"විස්තර බැලීමට ස්පර්ශ කරන්න"</string>
-    <string name="retry" msgid="7564024179122207376">"නැවත උත්සාහ කරන්න"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"මෙම ගොනු පිටපත් නොකරන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"මෙම ගොනු ගෙන නොයන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other">පසුරු පුවරුවට ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් පිටපත් කරන ලදි.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"මෙම ස්ථානය තුළ තෝරාගත් ගොනු ඇලවිය නොහැක."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"යළි නම් කරන්න"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ලේඛනය යළි නම් කිරීම අසාර්ථක විය"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index 2f0cbe8..882f513 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Zariadenia"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"Súbor sa nepodarilo 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>
@@ -90,6 +91,7 @@
     <string name="undo" msgid="7905788502491742328">"Späť"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="few">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
       <item quantity="many">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súboru</item>
@@ -102,8 +104,15 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Klepnutím zobrazíte podrobné informácie"</string>
-    <string name="retry" msgid="7564024179122207376">"Skúsiť znova"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Tieto súbory neboli skopírované: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Tieto súbory neboli presunuté: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -113,4 +122,6 @@
       <item quantity="one">Do schránky bol skopírovaný <xliff:g id="COUNT_0">%1$d</xliff:g> súbor.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Do tohto umiestnenia nie je možné prilepiť vybrané súbory"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Premenovať"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Premenovanie dokumentu zlyhalo"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index 6da1290..154fdb2 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Naprave"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Več aplikacij"</string>
     <string name="empty" msgid="7858882803708117596">"Ni elementov"</string>
+    <string name="no_results" msgid="6622510343880730446">"Tukaj ni ujemanj: %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Datoteke ni mogoče odpreti"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nekaterih dokumentov ni mogoče izbrisati"</string>
     <string name="share_via" msgid="8966594246261344259">"Deli z drugimi prek"</string>
@@ -90,6 +91,7 @@
     <string name="undo" msgid="7905788502491742328">"Razveljavi"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Pripravljanje na kopiranje …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Priprava na premikanje …"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Pripravljanje na izbris …"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke ni bilo mogoče kopirati</item>
       <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče kopirati</item>
@@ -102,8 +104,15 @@
       <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče premakniti</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče premakniti</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Dotaknite se za ogled podrobnosti"</string>
-    <string name="retry" msgid="7564024179122207376">"Poskusi znova"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke ni bilo mogoče izbrisati</item>
+      <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče izbrisati</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče izbrisati</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče izbrisati</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Dotaknite se za prikaz podrobnosti"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Te datoteke niso bile kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Te datoteke niso bile premaknjene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -113,4 +122,6 @@
       <item quantity="other">V odložišče je bilo kopiranih <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Izbranih datotek ni mogoče prilepiti sem."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Preimenuj"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Dokumenta ni bilo mogoče preimenovati"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
index b880bb4..bcb4ff0 100644
--- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml
+++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Pajisjet"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Aplikacione të tjera"</string>
     <string name="empty" msgid="7858882803708117596">"Nuk ka artikuj"</string>
+    <string name="no_results" msgid="6622510343880730446">"Nuk ka asnjë përputhje në %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Skedari nuk mund të hapet"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"E pamundur të fshihen disa dokumente"</string>
     <string name="share_via" msgid="8966594246261344259">"Shpërnda publikisht përmes"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Zhbëj"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Po përgatitet për kopjimin…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Po përgatitet për zhvendosjen…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Po përgatitet për fshirje…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skedarë nuk mund të kopjoheshin</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> skedar nuk mund të kopjohej</item>
@@ -92,8 +94,13 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skedarë nuk mund të zhvendoseshin</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> skedar nuk mund të zhvendosej</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Prek për të parë detajet"</string>
-    <string name="retry" msgid="7564024179122207376">"Provo përsëri"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skedarë nuk mund të fshiheshin</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> skedar nuk mund të fshihej</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Trokit për të parë detajet"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Këta skedarë nuk u kopjuan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Këta skedarë nuk u zhvendosën: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">U kopjua <xliff:g id="COUNT_0">%1$d</xliff:g> skedar në kujtesën e fragmenteve.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Skedarët e zgjedhur nuk mund të ngjiten në këtë vendndodhje."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Riemërto"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Riemërtimi i dokumentit dështoi"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index 93a1cf6..c0f8099 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Уређаји"</string>
     <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="1339885974067891667">"Није могуће отворити датотеку"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Није могуће избрисати неке документе"</string>
     <string name="share_via" msgid="8966594246261344259">"Делите преко"</string>
@@ -87,6 +88,7 @@
     <string name="undo" msgid="7905788502491742328">"Опозови"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Припрема се копирање…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Припрема се премештање..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Припрема се брисање…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -97,8 +99,14 @@
       <item quantity="few">Није успело премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотекe</item>
       <item quantity="other">Није успело премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Додирните да бисте видели детаље"</string>
-    <string name="retry" msgid="7564024179122207376">"Покушај поново"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Следеће датотеке нису копиране: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Ове датотеке нису премештене: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -107,4 +115,6 @@
       <item quantity="other">Копирали сте <xliff:g id="COUNT_1">%1$d</xliff:g> датотека у привремену меморију.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Изабране датотеке не могу да се налепе на овој локацији."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Преименуј"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Преименовање документа није успело"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index 63da2c6..e9af1f9 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Enheter"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Fler appar"</string>
     <string name="empty" msgid="7858882803708117596">"Inga objekt"</string>
+    <string name="no_results" msgid="6622510343880730446">"Det finns inga träffar i %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Det går inte att öppna filen"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Det gick inte att ta bort vissa dokument"</string>
     <string name="share_via" msgid="8966594246261344259">"Dela via"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Ångra"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopieringen förbereds …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Förbereder för att flytta …"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Radering förbereds …"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer gick inte att kopiera</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fil gick inte att kopiera</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Det gick inte att flytta <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
       <item quantity="one">Det gick inte att flytta <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Tryck här om du vill veta mer"</string>
-    <string name="retry" msgid="7564024179122207376">"Försök igen"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Det gick inte att radera <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
+      <item quantity="one">Det gick inte att radera <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Tryck om du vill visa informationen"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Följande filer kopierades inte: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Följande filer har inte flyttats: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fil har kopierats till Urklipp.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Det går inte att klistra in den valda filen på den här platsen."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Byt namn"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Det gick inte att byta namn på dokumentet"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index c303e0c..188f5b5 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Vifaa"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Programu zaidi"</string>
     <string name="empty" msgid="7858882803708117596">"Hakuna vipengee"</string>
+    <string name="no_results" msgid="6622510343880730446">"Hakuna zinazolingana katika %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Haiwezi kufungua faili"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Imeshindwa kufuta baadhi ya hati"</string>
     <string name="share_via" msgid="8966594246261344259">"Shiriki kupitia"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Tendua"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Inaanda kunakili..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Inatayarisha kuhamisha..."</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Inajitayarisha kufuta..."</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">Haikuweza kunakili faili <xliff:g id="COUNT_1">%1$d</xliff:g> </item>
       <item quantity="one">Haikuweza kunakili faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
@@ -92,8 +94,13 @@
       <item quantity="other">Haikuweza kuhamisha faili <xliff:g id="COUNT_1">%1$d</xliff:g></item>
       <item quantity="one">Haikuweza kuhamisha faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Gusa ili uone maelezo"</string>
-    <string name="retry" msgid="7564024179122207376">"Jaribu tena"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Haikuweza kufuta faili <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">Haikuweza kufuta faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Gonga ili uangalie maelezo"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Faili hizi hazikunakiliwa: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Faili hizi hazikuhamishwa: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Alinakili faili <xliff:g id="COUNT_0">%1$d</xliff:g> kwenye ubao wa kunakili.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Haiwezi kubandika faili zilizochaguliwa katika eneo hili."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Badilisha jina"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Imeshindwa kubadilisha jina la hati"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index 87cb68d..a6d52c4 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"சாதனங்கள்"</string>
     <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="1339885974067891667">"கோப்பைத் திறக்க முடியவில்லை"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"சில ஆவணங்களை நீக்க முடியவில்லை"</string>
     <string name="share_via" msgid="8966594246261344259">"இதன் வழியாகப் பகிர்"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"செயல்தவிர்"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"நகல் தயாராகிறது…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"நகர்த்துவதற்குத் தயார்படுத்துகிறது…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"நீக்கத் தயாராகிறது…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"விவரங்களைப் பார்க்க, தொடவும்"</string>
-    <string name="retry" msgid="7564024179122207376">"மீண்டும் முயற்சிக்கவும்"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"நகலெடுக்கப்படாத கோப்புகள்: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"இந்தக் கோப்புகள் நகர்த்தப்படவில்லை: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">கிளிப்போர்டிற்கு <xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பு நகலெடுக்கப்பட்டது.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"தேர்ந்தெடுத்த கோப்புகளை இங்கு ஒட்ட முடியாது."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"மறுபெயரிடு"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ஆவணத்திற்கு மறுபெயரிடுவதில் தோல்வி"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml
index 7b34df5..b2ac712 100644
--- a/packages/DocumentsUI/res/values-te-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"పరికరాలు"</string>
     <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="1339885974067891667">"ఫైల్‌ను తెరవడం సాధ్యపడదు"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"కొన్ని పత్రాలను తొలగించడం సాధ్యపడలేదు"</string>
     <string name="share_via" msgid="8966594246261344259">"దీని ద్వారా భాగస్వామ్యం చేయండి"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"చర్య రద్దు చేయి"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"కాపీ చేయడానికి సిద్ధం చేస్తోంది…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"తరలించడానికి సిద్ధమవుతోంది…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"తొలగించడానికి సిద్ధం చేస్తోంది…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"వివరాలను వీక్షించడానికి తాకండి"</string>
-    <string name="retry" msgid="7564024179122207376">"మళ్లీ ప్రయత్నించు"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ఈ ఫైల్‌లు కాపీ చేయబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ఈ ఫైల్‌లు తరలించబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">క్లిప్‌బోర్డ్‌కి <xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్‌ను కాపీ చేసారు.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ఎంచుకున్న ఫైల్‌లను ఈ స్థానంలోకి తీసుకురావడం సాధ్యపడదు."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"పేరు మార్చు"</string>
+    <string name="rename_error" msgid="4203041674883412606">"పత్రం పేరు మార్చడంలో విఫలమైంది"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index dfb423e..3261019 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"อุปกรณ์"</string>
     <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="1339885974067891667">"ไม่สามารถเปิดไฟล์ได้"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ไม่สามารถลบเอกสารบางรายการ"</string>
     <string name="share_via" msgid="8966594246261344259">"แชร์ผ่าน"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"เลิกทำ"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"กำลังเตรียมการคัดลอก…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"กำลังเตรียมการย้าย…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"กำลังเตรียมลบ…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"แตะเพื่อดูรายละเอียด"</string>
-    <string name="retry" msgid="7564024179122207376">"ลองอีกครั้ง"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"ไม่มีการคัดลอกไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"ไม่มีการย้ายไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">คัดลอก <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์ไปยังคลิปบอร์ดแล้ว</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ไม่สามารถวางไฟล์ที่เลือกในตำแหน่งนี้"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"เปลี่ยนชื่อ"</string>
+    <string name="rename_error" msgid="4203041674883412606">"ไม่สามารถเปลี่ยนชื่อเอกสาร"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index 813b39a..6548908 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Mga Device"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"I-undo"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <item quantity="one">Hindi nailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
       <item quantity="other">Hindi nailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Pindutin upang tingnan ang mga detalye"</string>
-    <string name="retry" msgid="7564024179122207376">"Subukang muli"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Hindi nakopya ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Hindi nailipat ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other">Nakopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file sa clipboard.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Hindi mai-paste sa lokasyong ito ang mga piniling file."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Palitan ang pangalan"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Hindi napalitan ang pangalan ng dokumento"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index 90794a2..2db4a1b 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Cihazlar"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Geri al"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Ayrıntıları görüntülemek için dokunun"</string>
-    <string name="retry" msgid="7564024179122207376">"Yeniden dene"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Şu dosyalar kopyalanmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Şu dosyalar taşınmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya panoya kopyalandı.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Seçili dosyalar bu konuma yapıştırılamıyor."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Yeniden Adlandır"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Dokümanın adı değiştirilemedi"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index a8278d9..8624aec 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Пристрої"</string>
     <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="1339885974067891667">"Не вдалося відкрити файл"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Не вдалося видалити деякі документи"</string>
     <string name="share_via" msgid="8966594246261344259">"Надіслати через"</string>
@@ -90,6 +91,7 @@
     <string name="undo" msgid="7905788502491742328">"Відмінити"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Підготовка до копіювання…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Підготовка до переміщення…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Підготовка до видалення…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -102,8 +104,15 @@
       <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="4483108577842961665">"Торкніться, щоб дізнатися більше"</string>
-    <string name="retry" msgid="7564024179122207376">"Повторити"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ці файли не скопійовано: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Не переміщено ці файли: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -113,4 +122,6 @@
       <item quantity="other">У буфер обміну скопійовано <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Не вдається вставити вибрані файли в цю папку."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Перейменувати"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Не вдалося перейменувати документ"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index d8caa37..6ddad5f 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"آلات"</string>
     <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="1339885974067891667">"فائل نہيں کھول سکتے ہیں"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"کچھ دستاویزات کو حذف کرنے سے قاصر"</string>
     <string name="share_via" msgid="8966594246261344259">"اشتراک کریں بذریعہ"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"کالعدم کریں"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"کاپی کیلئے تیار ہو رہا ہے…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"منتقلی کیلئے تیار ہو رہی ہیں…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"حذف کرنے کیلئے تیاری ہو رہی ہے…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"تفصیلات دیکھنے کیلئے ٹچ کریں"</string>
-    <string name="retry" msgid="7564024179122207376">"دوبارہ کوشش کریں"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"یہ فائلز کاپی نہیں کی گئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"یہ فائلیں منتقل نہیں ہوئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل کلپ بورڈ پر کاپی کی گئی۔</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"منتخب کردہ فائلز کو اس مقام پر پیسٹ نہیں کیا جا سکتا۔"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"نام تبدیل کریں"</string>
+    <string name="rename_error" msgid="4203041674883412606">"دستاویز کا نام تبدیل کرنے میں ناکام"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index 1b5ace4..78e48c6 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Qurilmalar"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"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>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Bekor qilish"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayldan nusxa olinmadi</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayldan nusxa olinmadi</item>
@@ -92,8 +94,13 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmadi</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmadi</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Batafsil ma’lumot olish uchun bosing"</string>
-    <string name="retry" msgid="7564024179122207376">"Qayta urinish"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ushbu fayllardan nusxa olinmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Ushbu fayllar ko‘chirib o‘tkazilmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayldan vaqtinchalik xotiraga nusxa olindi.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Tanlangan fayllarni bu yerga joylab bo‘lmadi."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Qayta nomlash"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Hujjatni qayta nomlab bo‘lmadi"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index 287ca70..3f44f62 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Thiết bị"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Các ứng dụng khác"</string>
     <string name="empty" msgid="7858882803708117596">"Không có mục nào"</string>
+    <string name="no_results" msgid="6622510343880730446">"Không có kết quả phù hợp trong %1$s"</string>
     <string name="toast_no_application" msgid="1339885974067891667">"Không thể mở tệp"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Không thể xóa một số tài liệu"</string>
     <string name="share_via" msgid="8966594246261344259">"Chia sẻ qua"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Hoàn tác"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"Đang chuẩn bị sao chép…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Đang chuẩn bị di chuyển…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"Đang chuẩn bị xóa…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <item quantity="other">Không thể sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> tệp</item>
       <item quantity="one">Không thể sao chép <xliff:g id="COUNT_0">%1$d</xliff:g> tệp</item>
@@ -92,8 +94,13 @@
       <item quantity="other">Không thể di chuyển <xliff:g id="COUNT_1">%1$d</xliff:g> tệp</item>
       <item quantity="one">Không thể di chuyển <xliff:g id="COUNT_0">%1$d</xliff:g> tệp</item>
     </plurals>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Chạm để xem chi tiết"</string>
-    <string name="retry" msgid="7564024179122207376">"Thử lại"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <item quantity="other">Không thể xóa <xliff:g id="COUNT_1">%1$d</xliff:g> tệp</item>
+      <item quantity="one">Không thể xóa <xliff:g id="COUNT_0">%1$d</xliff:g> tệp</item>
+    </plurals>
+    <string name="notification_touch_for_details" msgid="6268189413228855582">"Nhấn để xem chi tiết"</string>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Những tệp này chưa được sao chép: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Những tệp này chưa được di chuyển: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">Đã sao chép <xliff:g id="COUNT_0">%1$d</xliff:g> tệp vào khay nhớ tạm.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Không thể dán các tệp đã chọn vào vị trí này."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Đổi tên"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Không đổi được tên tài liệu"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index 9901abf..c8b4a82 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"设备"</string>
     <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="1339885974067891667">"无法打开文件"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"无法删除部分文档"</string>
     <string name="share_via" msgid="8966594246261344259">"分享方式"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"撤消"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"正在准备复制…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"正在准备移动…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"正在准备删除…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"触摸可查看详情"</string>
-    <string name="retry" msgid="7564024179122207376">"重试"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"以下文件无法复制:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"以下文件无法移动:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">已将 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件复制到剪贴板。</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"无法将所选文件粘贴到此位置。"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"重命名"</string>
+    <string name="rename_error" msgid="4203041674883412606">"无法重命名文档"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index 9cfba1d..46c1be3 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"裝置"</string>
     <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="1339885974067891667">"無法開啟檔案"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
     <string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"復原"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"正在準備移動…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"正在準備刪除…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"輕觸即可查看詳情"</string>
-    <string name="retry" msgid="7564024179122207376">"重試"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"以下檔案未能複製:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"這些檔案並未移動:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">已複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案到剪貼簿。</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"無法在此位置貼上選取檔案。"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"重新命名"</string>
+    <string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index b2cee9c..1502176 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"裝置"</string>
     <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="1339885974067891667">"無法開啟檔案"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
     <string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"復原"</string>
     <string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"準備移動…"</string>
+    <string name="delete_preparing" msgid="5655813182533491992">"正在準備刪除…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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="4483108577842961665">"輕觸即可查看詳細資料"</string>
-    <string name="retry" msgid="7564024179122207376">"重試"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"未複製這些檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"未移動以下檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="one">已將 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案複製到剪貼簿。</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"無法將所選檔案貼到這個位置。"</string>
+    <string name="menu_rename" msgid="7678802479104285353">"重新命名"</string>
+    <string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index 308a6f9..44f82cf 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -63,6 +63,7 @@
     <string name="root_type_device" msgid="7121342474653483538">"Amadivayisi"</string>
     <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>
     <string name="toast_no_application" msgid="1339885974067891667">"Ayikwazi ukuvula ifayela"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ayikwazi ukususa amanye amadokhumenti"</string>
     <string name="share_via" msgid="8966594246261344259">"Yabelana nge-"</string>
@@ -84,6 +85,7 @@
     <string name="undo" msgid="7905788502491742328">"Hlehlisa"</string>
     <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>
     <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
       <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>
@@ -92,8 +94,13 @@
       <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>
-    <string name="notification_touch_for_details" msgid="4483108577842961665">"Thinta ukuze ubuke imininingwane"</string>
-    <string name="retry" msgid="7564024179122207376">"Zama futhi"</string>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+      <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>
+    <!-- no translation found for close (3043722427445528732) -->
+    <skip />
     <string name="copy_failure_alert_content" msgid="3715575000297709082">"Lawa mafayela awazange akopishwe: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="7151140279020481180">"Lawa mafayela awazange ahanjiswe: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
@@ -101,4 +108,6 @@
       <item quantity="other">Kukopishwe amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g> kubhodi lokunamathisela.</item>
     </plurals>
     <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Ayikwazi ukunamathisela amafayela akhethiwe kule ndawo."</string>
+    <string name="menu_rename" msgid="7678802479104285353">"Qamba kabusha"</string>
+    <string name="rename_error" msgid="4203041674883412606">"Yehlulekile ukuqamba kabusha idokhumenti"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index f926245..aefdc67 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -65,13 +65,9 @@
     <string name="menu_paste_from_clipboard">Paste</string>
 
     <!-- Menu item that reveals internal storage built into the device [CHAR LIMIT=24] -->
-    <string name="menu_advanced_show" product="nosdcard">Show internal storage</string>
-    <!-- Menu item that reveals SD cards built into the device [CHAR LIMIT=24] -->
-    <string name="menu_advanced_show" product="default">Show SD card</string>
+    <string name="menu_advanced_show">Show internal storage</string>
     <!-- Menu item that hides internal storage built into the device [CHAR LIMIT=24] -->
-    <string name="menu_advanced_hide" product="nosdcard">Hide internal storage</string>
-    <!-- Menu item that hides SD cards built into the device [CHAR LIMIT=24] -->
-    <string name="menu_advanced_hide" product="default">Hide SD card</string>
+    <string name="menu_advanced_hide">Hide internal storage</string>
 
     <!-- Menu item that reveals the sizes of displayed files [CHAR LIMIT=24] -->
     <string name="menu_file_size_show">Show file size</string>
@@ -178,9 +174,9 @@
         <item quantity="other">Couldn\'t delete <xliff:g id="count" example="2">%1$d</xliff:g> files</item>
     </plurals>
     <!-- Second line for notifications saying that more information will be shown after touching [CHAR LIMIT=48] -->
-    <string name="notification_touch_for_details">Touch to view details</string>
-    <!-- Label of a dialog button for retrying a failed operation [CHAR LIMIT=24] -->
-    <string name="retry">Retry</string>
+    <string name="notification_touch_for_details">Tap to view details</string>
+    <!-- Label of the close dialog button.[CHAR LIMIT=24] -->
+    <string name="close">Close</string>
     <!-- Contents of the copying failure alert dialog. [CHAR LIMIT=48] -->
     <string name="copy_failure_alert_content">These files weren\'t copied: <xliff:g id="list">%1$s</xliff:g></string>
     <!-- Contents of the moving failure alert dialog. [CHAR LIMIT=48] -->
@@ -192,4 +188,17 @@
     </plurals>
     <!-- Toast shown when a user tries to paste files into an unsupported location. -->
     <string name="clipboard_files_cannot_paste">Cannot paste the selected files in this location.</string>
+    <!-- Menu item that renames the selected document [CHAR LIMIT=24] -->
+    <string name="menu_rename">Rename</string>
+    <!-- Toast shown when renaming document failed with an error [CHAR LIMIT=48] -->
+    <string name="rename_error">Failed to rename document</string>
+
+    <!--  DO NOT TRANSLATE - final phrase has not been decided yet (b/26750152) -->
+    <string name="open_external_dialog_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
+        access to <xliff:g id="directory" example="Pictures"><i>^2</i></xliff:g> folder on
+        <xliff:g id="storage" example="SD Card"><i>^3</i></xliff:g>?</string>
+    <!-- Text in the button asking user to allow access to a given directory. -->
+    <string name="allow">Allow</string>
+    <!-- Text in the button asking user to deny access to a given directory. -->
+    <string name="deny">Deny</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index d14631d..f4dfd73 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -45,4 +45,8 @@
         <item name="android:maxHeight">3dp</item>    
     </style>
 
+    <!--  TODO: use the proper dialog and/or inline if not overriding -->
+    <style name="AlertDialogTheme" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
+    </style>
+
 </resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 0fb8daf..ad8b0d1 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -107,6 +107,8 @@
                 ? icicle.<State>getParcelable(EXTRA_STATE)
                         : buildState();
 
+        Metrics.logActivityLaunch(this, mState, getIntent());
+
         setContentView(mLayoutId);
 
         mRoots = DocumentsApplication.getRootsCache(this);
@@ -437,7 +439,7 @@
         DirectoryFragment.get(getFragmentManager()).onUserModeChanged();
     }
 
-    void setPending(boolean pending) {
+    public void setPending(boolean pending) {
         final SaveFragment save = SaveFragment.get(getFragmentManager());
         if (save != null) {
             save.setPending(pending);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index f3c3f2f..df036b9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -63,7 +63,7 @@
         final AlertDialog.Builder builder = new AlertDialog.Builder(context);
         final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
 
-        final View view = dialogInflater.inflate(R.layout.dialog_create_dir, null, false);
+        final View view = dialogInflater.inflate(R.layout.dialog_file_name, null, false);
         final EditText editText = (EditText) view.findViewById(android.R.id.text1);
 
         builder.setTitle(R.string.menu_create_dir);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FailureDialogFragment.java b/packages/DocumentsUI/src/com/android/documentsui/FailureDialogFragment.java
index 7f6f1c6..b8ef5ac 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FailureDialogFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FailureDialogFragment.java
@@ -33,17 +33,14 @@
 import com.android.documentsui.services.FileOperations;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Alert dialog for failed operations.
  */
-public class FailureDialogFragment extends DialogFragment
-        implements DialogInterface.OnClickListener {
+public class FailureDialogFragment extends DialogFragment {
     private static final String TAG = "FailureDialogFragment";
 
-    private int mOperationType;
-    private ArrayList<DocumentInfo> mFailedSrcList;
-
     public static void show(FragmentManager fm, int failure,
             ArrayList<DocumentInfo> failedSrcList, DocumentStack dstStack, int operationType) {
         // TODO: Add support for other failures than copy.
@@ -65,36 +62,25 @@
     }
 
     @Override
-    public void onClick(DialogInterface dialog, int whichButton) {
-        if (whichButton == DialogInterface.BUTTON_POSITIVE) {
-            FileOperations.start(
-                    getActivity(),
-                    mFailedSrcList,
-                    (DocumentStack) getActivity().getIntent().getParcelableExtra(
-                            Shared.EXTRA_STACK),
-                    mOperationType);
-        }
-    }
-
-    @Override
     public Dialog onCreateDialog(Bundle inState) {
         super.onCreate(inState);
 
-        mOperationType = getArguments().getInt(FileOperationService.EXTRA_OPERATION);
-        mFailedSrcList = getArguments().getParcelableArrayList(FileOperationService.EXTRA_SRC_LIST);
+        final int operationType = getArguments().getInt(FileOperationService.EXTRA_OPERATION);
+        final List<DocumentInfo> failedSrcList = getArguments().getParcelableArrayList(
+                FileOperationService.EXTRA_SRC_LIST);
 
         final StringBuilder list = new StringBuilder("<p>");
-        for (DocumentInfo documentInfo : mFailedSrcList) {
+        for (DocumentInfo documentInfo : failedSrcList) {
             list.append(String.format("&#8226; %s<br>", documentInfo.displayName));
         }
         list.append("</p>");
 
         // TODO: Add support for other file operations.
         checkArgument(
-                mOperationType == FileOperationService.OPERATION_COPY
-                || mOperationType == FileOperationService.OPERATION_MOVE);
+                operationType == FileOperationService.OPERATION_COPY
+                || operationType == FileOperationService.OPERATION_MOVE);
 
-        int messageId = mOperationType == FileOperationService.OPERATION_COPY
+        int messageId = operationType == FileOperationService.OPERATION_COPY
                 ? R.string.copy_failure_alert_content
                 : R.string.move_failure_alert_content;
 
@@ -105,8 +91,12 @@
 
         return new AlertDialog.Builder(getActivity())
                 .setMessage(Html.fromHtml(message))
-                .setPositiveButton(R.string.retry, this)
-                .setNegativeButton(android.R.string.cancel, this)
+                .setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int id) {
+                        dialog.dismiss();
+                    }
+                })
                 .create();
     }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index 58537ee..5abe7f6 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -282,6 +282,7 @@
     }
 
     private void createNewWindow() {
+        Metrics.logMultiWindow(this);
         Intent intent = LauncherActivity.createLaunchIntent(this);
         intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack);
         startActivity(intent);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
new file mode 100644
index 0000000..eb90b75
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.Shared.DEBUG;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.util.Log;
+
+import com.android.documentsui.model.RootInfo;
+import com.android.internal.logging.MetricsLogger;
+
+/** @hide */
+public final class Metrics {
+    private static final String TAG = "Metrics";
+
+    // These are the native provider authorities that the metrics code is capable of recognizing and
+    // explicitly counting.
+    private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents";
+    private static final String AUTHORITY_STORAGE = "com.android.externalstorage.documents";
+    private static final String AUTHORITY_DOWNLOADS = "com.android.providers.downloads.documents";
+
+    // These strings have to be whitelisted in tron. Do not change them.
+    private static final String COUNT_LAUNCH_ACTION = "docsui_launch_action";
+    private static final String COUNT_ROOT_VISITED = "docsui_root_visited";
+    private static final String COUNT_OPEN_MIME = "docsui_open_mime";
+    private static final String COUNT_CREATE_MIME = "docsui_create_mime";
+    private static final String COUNT_GET_CONTENT_MIME = "docsui_get_content_mime";
+    private static final String COUNT_BROWSE_ROOT = "docsui_browse_root";
+    private static final String COUNT_MANAGE_ROOT = "docsui_manage_root";
+    private static final String COUNT_MULTI_WINDOW = "docsui_multi_window";
+
+    // Indices for bucketing roots in the roots histogram. "Other" is the catch-all index for any
+    // root that is not explicitly recognized by the Metrics code (see {@link
+    // #getSanitizedRootIndex}). Apps are also bucketed in this histogram using negative indices
+    // (see below).
+    private static final int ROOT_NONE = 0;
+    private static final int ROOT_OTHER = 1;
+    private static final int ROOT_AUDIO = 2;
+    private static final int ROOT_DEVICE_STORAGE = 3;
+    private static final int ROOT_DOWNLOADS = 4;
+    private static final int ROOT_HOME = 5;
+    private static final int ROOT_IMAGES = 6;
+    private static final int ROOT_RECENTS = 7;
+    private static final int ROOT_VIDEOS = 8;
+    // Apps aren't really "roots", but they are treated as such in the roots fragment UI and so they
+    // are logged analogously to roots. Use negative numbers to identify apps.
+    private static final int ROOT_THIRD_PARTY_APP = -1;
+
+    // Indices for bucketing mime types.
+    private static final int MIME_OTHER = -2; // anything not enumerated below
+    private static final int MIME_NONE = -1; // null mime
+    private static final int MIME_ANY = 0; // */*
+    private static final int MIME_APPLICATION = 1; // application/*
+    private static final int MIME_AUDIO = 2; // audio/*
+    private static final int MIME_IMAGE = 3; // image/*
+    private static final int MIME_MESSAGE = 4; // message/*
+    private static final int MIME_MULTIPART = 5; // multipart/*
+    private static final int MIME_TEXT = 6; // text/*
+    private static final int MIME_VIDEO = 7; // video/*
+
+    /**
+     * Logs when DocumentsUI is started, and how. Call this when DocumentsUI first starts up.
+     *
+     * @param context
+     * @param state
+     * @param intent
+     */
+    public static void logActivityLaunch(Context context, State state, Intent intent) {
+        // Log the launch action.
+        logHistogram(context, COUNT_LAUNCH_ACTION, state.action);
+        // Then log auxiliary data (roots/mime types) associated with some actions.
+        Uri uri = intent.getData();
+        switch (state.action) {
+            case State.ACTION_OPEN:
+                logHistogram(context, COUNT_OPEN_MIME, sanitizeMime(intent.getType()));
+                break;
+            case State.ACTION_CREATE:
+                logHistogram(context, COUNT_CREATE_MIME, sanitizeMime(intent.getType()));
+                break;
+            case State.ACTION_GET_CONTENT:
+                logHistogram(context, COUNT_GET_CONTENT_MIME, sanitizeMime(intent.getType()));
+                break;
+            case State.ACTION_MANAGE:
+                logHistogram(context, COUNT_MANAGE_ROOT, sanitizeRoot(uri));
+                break;
+            case State.ACTION_BROWSE:
+                logHistogram(context, COUNT_BROWSE_ROOT, sanitizeRoot(uri));
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Logs a root visited event. Call this when the user clicks on a root in the RootsFragment.
+     *
+     * @param context
+     * @param info
+     */
+    public static void logRootVisited(Context context, RootInfo info) {
+        logHistogram(context, COUNT_ROOT_VISITED, sanitizeRoot(info));
+    }
+
+    /**
+     * Logs an app visited event. Call this when the user clicks on an app in the RootsFragment.
+     *
+     * @param context
+     * @param info
+     */
+    public static void logAppVisited(Context context, ResolveInfo info) {
+        logHistogram(context, COUNT_ROOT_VISITED, sanitizeRoot(info));
+    }
+
+    /**
+     * Logs a multi-window start. Call this when the user spawns a new DocumentsUI window.
+     *
+     * @param context
+     */
+    public static void logMultiWindow(Context context) {
+        logCount(context, COUNT_MULTI_WINDOW);
+    }
+
+    /**
+     * Internal method for making a MetricsLogger.count call. Increments the given counter by 1.
+     *
+     * @param context
+     * @param name The counter to increment.
+     */
+    private static void logCount(Context context, String name) {
+        if (DEBUG) Log.d(TAG, name + ": " + 1);
+        MetricsLogger.count(context, name, 1);
+    }
+
+    /**
+     * Internal method for making a MetricsLogger.histogram call.
+     *
+     * @param context
+     * @param name The name of the histogram.
+     * @param bucket The bucket to increment.
+     */
+    private static void logHistogram(Context context, String name, int bucket) {
+        if (DEBUG) Log.d(TAG, name + ": " + bucket);
+        MetricsLogger.histogram(context, name, bucket);
+    }
+
+    /**
+     * Generates an integer identifying the given root. For privacy, this function only recognizes a
+     * small set of hard-coded roots (ones provided by the system). Other roots are all grouped into
+     * a single ROOT_OTHER bucket.
+     */
+    private static int sanitizeRoot(Uri uri) {
+        if (LauncherActivity.isLaunchUri(uri)) {
+            return ROOT_NONE;
+        }
+
+        switch (uri.getAuthority()) {
+            case AUTHORITY_MEDIA:
+                switch (DocumentsContract.getRootId(uri)) {
+                    case "audio_root":
+                        return ROOT_AUDIO;
+                    case "images_root":
+                        return ROOT_IMAGES;
+                    case "videos_root":
+                        return ROOT_VIDEOS;
+                    default:
+                        return ROOT_OTHER;
+                }
+            case AUTHORITY_STORAGE:
+                if ("home".equals(DocumentsContract.getRootId(uri))) {
+                    return ROOT_HOME;
+                } else {
+                    return ROOT_DEVICE_STORAGE;
+                }
+            case AUTHORITY_DOWNLOADS:
+                return ROOT_DOWNLOADS;
+            default:
+                return ROOT_OTHER;
+        }
+    }
+
+    /** @see #sanitizeRoot(Uri) */
+    private static int sanitizeRoot(RootInfo root) {
+        if (root.isRecents()) {
+            // Recents root is special and only identifiable via this method call. Other roots are
+            // identified by URI.
+            return ROOT_RECENTS;
+        } else {
+            return sanitizeRoot(root.getUri());
+        }
+    }
+
+    /** @see #sanitizeRoot(Uri) */
+    private static int sanitizeRoot(ResolveInfo info) {
+        // Log all apps under a single bucket in the roots histogram.
+        return ROOT_THIRD_PARTY_APP;
+    }
+
+    /**
+     * Generates an int identifying a mime type. For privacy, this function only recognizes a small
+     * set of hard-coded types. For any other type, this function returns "other".
+     *
+     * @param mimeType
+     * @return
+     */
+    private static int sanitizeMime(String mimeType) {
+        if (mimeType == null) {
+            return MIME_NONE;
+        } else if ("*/*".equals(mimeType)) {
+            return MIME_ANY;
+        } else {
+            String type = mimeType.substring(0, mimeType.indexOf('/'));
+            switch (type) {
+                case "application":
+                    return MIME_APPLICATION;
+                case "audio":
+                    return MIME_AUDIO;
+                case "image":
+                    return MIME_IMAGE;
+                case "message":
+                    return MIME_MESSAGE;
+                case "multipart":
+                    return MIME_MULTIPART;
+                case "text":
+                    return MIME_TEXT;
+                case "video":
+                    return MIME_VIDEO;
+            }
+        }
+        // Bucket all other types into one bucket.
+        return MIME_OTHER;
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java b/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
new file mode 100644
index 0000000..5dc4f57
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 android.os.Environment.isStandardDirectory;
+import static com.android.documentsui.Shared.DEBUG;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.ContentProvider;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.provider.DocumentsContract;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Activity responsible for handling {@link Intent#ACTION_OPEN_EXTERNAL_DOCUMENT}.
+ */
+public class OpenExternalDirectoryActivity extends Activity {
+    private static final String TAG = "OpenExternalDirectoryActivity";
+    private static final String FM_TAG = "open_external_directory";
+    private static final String EXTERNAL_STORAGE_AUTH = "com.android.externalstorage.documents";
+    private static final String EXTRA_FILE = "com.android.documentsui.FILE";
+    private static final String EXTRA_APP_LABEL = "com.android.documentsui.APP_LABEL";
+    private static final String EXTRA_VOLUME_LABEL = "com.android.documentsui.VOLUME_LABEL";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final Intent intent = getIntent();
+        if (intent == null || intent.getData() == null) {
+            Log.d(TAG, "missing intent or intent data: " + intent);
+            setResult(RESULT_CANCELED);
+            finish();
+            return;
+        }
+
+        final String path = intent.getData().getPath();
+        final int userId = UserHandle.myUserId();
+        if (!showFragment(this, userId, path)) {
+            setResult(RESULT_CANCELED);
+            finish();
+            return;
+        }
+    }
+
+    /**
+     * Validates the given {@code path} 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;
+        }
+        File file;
+        try {
+            file = new File(new File(path).getCanonicalPath());
+        } catch (IOException e) {
+            Log.e(TAG, "Could not get canonical file from " + path);
+            return false;
+        }
+        final StorageManager sm =
+                (StorageManager) activity.getSystemService(Context.STORAGE_SERVICE);
+
+        final String root = file.getParent();
+        final String directory = file.getName();
+
+        // Verify directory is valid.
+        if (TextUtils.isEmpty(directory) || !isStandardDirectory(directory)) {
+            Log.d(TAG, "Directory '" + directory + "' is not standard (full path: '" + path + "')");
+            return false;
+        }
+
+        // Gets volume label and converted path
+        String volumeLabel = null;
+        final List<VolumeInfo> volumes = sm.getVolumes();
+        if (DEBUG) Log.d(TAG, "Number of volumes: " + volumes.size());
+        for (VolumeInfo volume : volumes) {
+            if (isRightVolume(volume, root, userId)) {
+                final File internalRoot = volume.getInternalPathForUser(userId);
+                // Must convert path before calling getDocIdForFileCreateNewDir()
+                if (DEBUG) Log.d(TAG, "Converting " + root + " to " + internalRoot);
+                file = new File(internalRoot, directory);
+                volumeLabel = sm.getBestVolumeDescription(volume);
+                break;
+            }
+        }
+        if (volumeLabel == null) {
+            Log.e(TAG, "Could not get volume for " + path);
+            return false;
+        }
+
+        // Gets the package label.
+        final String appLabel = getAppLabel(activity);
+        if (appLabel == null) {
+            return false;
+        }
+
+        // Sets args that will be retrieve on onCreate()
+        final Bundle args = new Bundle();
+        args.putString(EXTRA_FILE, file.getAbsolutePath());
+        args.putString(EXTRA_VOLUME_LABEL, volumeLabel);
+        args.putString(EXTRA_APP_LABEL, appLabel);
+
+        final FragmentManager fm = activity.getFragmentManager();
+        final FragmentTransaction ft = fm.beginTransaction();
+        final OpenExternalDirectoryDialogFragment fragment =
+                new OpenExternalDirectoryDialogFragment();
+        fragment.setArguments(args);
+        ft.add(fragment, FM_TAG);
+        ft.commitAllowingStateLoss();
+
+        return true;
+    }
+
+    private static String getAppLabel(Activity activity) {
+        final String packageName = activity.getCallingPackage();
+        final PackageManager pm = activity.getPackageManager();
+        try {
+            return pm.getApplicationLabel(pm.getApplicationInfo(packageName, 0)).toString();
+        } catch (NameNotFoundException e) {
+            Log.w(TAG, "Could not get label for package " + packageName);
+            return null;
+        }
+    }
+
+    private static boolean isRightVolume(VolumeInfo volume, String root, int userId) {
+        final File userPath = volume.getPathForUser(userId);
+        final String path = userPath == null ? null : volume.getPathForUser(userId).getPath();
+        final boolean isVisible = volume.isVisibleForWrite(userId);
+        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);
+    }
+
+    private static Intent createGrantedUriPermissionsIntent(ContentProviderClient provider,
+            File file) {
+        // Calls ExternalStorageProvider to get the doc id for the file
+        final Bundle bundle;
+        try {
+            bundle = provider.call("getDocIdForFileCreateNewDir", file.getPath(), null);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Did not get doc id from External Storage provider for " + file, e);
+            return null;
+        }
+        final String docId = bundle == null ? null : bundle.getString("DOC_ID");
+        if (docId == null) {
+            Log.e(TAG, "Did not get doc id from External Storage provider for " + file);
+            return null;
+        }
+        Log.d(TAG, "doc id for " + file + ": " + docId);
+
+        final Uri uri = DocumentsContract.buildTreeDocumentUri(EXTERNAL_STORAGE_AUTH, docId);
+        if (uri == null) {
+            Log.e(TAG, "Could not get URI for doc id " + docId);
+            return null;
+        }
+
+        if (DEBUG) Log.d(TAG, "URI for " + file + ": " + uri);
+        final Intent intent = new Intent();
+        intent.setData(uri);
+        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
+                | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
+        return intent;
+    }
+
+    private static class OpenExternalDirectoryDialogFragment extends DialogFragment {
+
+        private File mFile;
+        private String mVolumeLabel;
+        private String mAppLabel;
+        private ContentProviderClient mExternalStorageClient;
+        private ContentResolver mResolver;
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            final Bundle args = getArguments();
+            if (args != null) {
+                mFile = new File(args.getString(EXTRA_FILE));
+                mVolumeLabel = args.getString(EXTRA_VOLUME_LABEL);
+                mAppLabel = args.getString(EXTRA_APP_LABEL);
+                mResolver = getContext().getContentResolver();
+            }
+        }
+
+        @Override
+        public void onDestroy() {
+            super.onDestroy();
+            if (mExternalStorageClient != null) {
+                mExternalStorageClient.close();
+            }
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final String folder = mFile.getName();
+            final Activity activity = getActivity();
+            final OnClickListener listener = new OnClickListener() {
+
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    Intent intent = null;
+                    if (which == DialogInterface.BUTTON_POSITIVE) {
+                        intent = createGrantedUriPermissionsIntent(getExternalStorageClient(),
+                                mFile);
+                    }
+                    if (which == DialogInterface.BUTTON_NEGATIVE || intent == null) {
+                        activity.setResult(RESULT_CANCELED);
+                    } else {
+                        activity.setResult(RESULT_OK, intent);
+                    }
+                    activity.finish();
+                }
+            };
+
+            final CharSequence message = TextUtils
+                    .expandTemplate(
+                            getText(R.string.open_external_dialog_request), mAppLabel, folder,
+                            mVolumeLabel);
+            return new AlertDialog.Builder(activity, R.style.AlertDialogTheme)
+                    .setMessage(message)
+                    .setPositiveButton(R.string.allow, listener)
+                    .setNegativeButton(R.string.deny, listener)
+                    .create();
+        }
+
+        @Override
+        public void onCancel(DialogInterface dialog) {
+            super.onCancel(dialog);
+            final Activity activity = getActivity();
+            activity.setResult(RESULT_CANCELED);
+            activity.finish();
+        }
+
+        private synchronized ContentProviderClient getExternalStorageClient() {
+            if (mExternalStorageClient == null) {
+                mExternalStorageClient =
+                        mResolver.acquireContentProviderClient(EXTERNAL_STORAGE_AUTH);
+            }
+            return mExternalStorageClient;
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index beff196..c2aeb86 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -180,10 +180,14 @@
             Item item = mAdapter.getItem(position);
             if (item instanceof RootItem) {
                 BaseActivity activity = BaseActivity.get(RootsFragment.this);
-                activity.onRootPicked(((RootItem) item).root);
+                RootInfo info = ((RootItem) item).root;
+                Metrics.logRootVisited(getActivity(), info);
+                activity.onRootPicked(info);
             } else if (item instanceof AppItem) {
                 DocumentsActivity activity = DocumentsActivity.get(RootsFragment.this);
-                activity.onAppPicked(((AppItem) item).info);
+                ResolveInfo info = ((AppItem) item).info;
+                Metrics.logAppVisited(getActivity(), info);
+                activity.onAppPicked(info);
             } else if (item instanceof SpacerItem) {
                 if (DEBUG) Log.d(TAG, "Ignoring click on spacer item.");
             } else {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index bfd40bb..74fa8d0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -93,6 +93,7 @@
 import com.android.documentsui.RecentLoader;
 import com.android.documentsui.RecentsProvider;
 import com.android.documentsui.RecentsProvider.StateColumns;
+import com.android.documentsui.dirlist.RenameDocumentFragment;
 import com.android.documentsui.RootsCache;
 import com.android.documentsui.Shared;
 import com.android.documentsui.Snackbars;
@@ -384,6 +385,7 @@
         FileOperations.start(
                 getActivity(),
                 getDisplayState().selectedDocumentsForCopy,
+                getDisplayState().stack.peek(),
                 (DocumentStack) data.getParcelableExtra(Shared.EXTRA_STACK),
                 operationType);
     }
@@ -559,6 +561,7 @@
         private Selection mSelected = new Selection();
         private ActionMode mActionMode;
         private int mNoDeleteCount = 0;
+        private int mNoRenameCount = -1;
         private Menu mMenu;
 
         @Override
@@ -582,6 +585,9 @@
             if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) {
                 mNoDeleteCount += selected ? 1 : -1;
             }
+            if ((docFlags & Document.FLAG_SUPPORTS_RENAME) != 0) {
+                mNoRenameCount += selected ? 1 : -1;
+            }
         }
 
         @Override
@@ -620,6 +626,7 @@
             mSelectionManager.clearSelection();
             mSelected.clear();
             mNoDeleteCount = 0;
+            mNoRenameCount = -1;
         }
 
         @Override
@@ -637,10 +644,19 @@
             return true;
         }
 
+        boolean canRenameSelection() {
+            return mNoRenameCount == 0 && mSelectionManager.getSelection().size() == 1;
+        }
+
+        boolean canDeleteSelection() {
+            return mNoDeleteCount == 0;
+        }
+
         private void updateActionMenu() {
             checkNotNull(mMenu);
+
             // Delegate update logic to our owning action, since specialized logic is desired.
-            mTuner.updateActionMenu(mMenu, mType, mNoDeleteCount == 0);
+            mTuner.updateActionMenu(mMenu, mType, canDeleteSelection(), canRenameSelection());
             Menus.disableHiddenItems(mMenu);
         }
 
@@ -680,6 +696,7 @@
                 case R.id.menu_copy_to_clipboard:
                     if (!selection.isEmpty()) {
                         copySelectionToClipboard(selection);
+                        mode.finish();
                     }
                     return true;
 
@@ -687,6 +704,11 @@
                     selectAllFiles();
                     return true;
 
+                case R.id.menu_rename:
+                    renameDocuments(selection);
+                    mode.finish();
+                    return true;
+
                 default:
                     if (DEBUG) Log.d(TAG, "Unhandled menu item selected: " + item);
                     return false;
@@ -761,20 +783,21 @@
 
     private void deleteDocuments(final Selection selected) {
 
-            checkArgument(!selected.isEmpty());
-            new GetDocumentsTask() {
-                @Override
-                void onDocumentsReady(List<DocumentInfo> docs) {
-                    // Hide the files in the UI.
-                    final SparseArray<String> hidden = mAdapter.hide(selected.getAll());
+        checkArgument(!selected.isEmpty());
+        final DocumentInfo srcParent = getDisplayState().stack.peek();
+        new GetDocumentsTask() {
+            @Override
+            void onDocumentsReady(List<DocumentInfo> docs) {
+                // Hide the files in the UI.
+                final SparseArray<String> hidden = mAdapter.hide(selected.getAll());
 
-                    checkState(DELETE_JOB_DELAY > DELETE_UNDO_TIMEOUT);
-                    String operationId = FileOperations.delete(
-                            getActivity(), docs, getDisplayState().stack,
-                            DELETE_JOB_DELAY);
-                    showDeleteSnackbar(hidden, operationId);
-                }
-            }.execute(selected);
+                checkState(DELETE_JOB_DELAY > DELETE_UNDO_TIMEOUT);
+                String operationId = FileOperations.delete(
+                        getActivity(), docs, srcParent, getDisplayState().stack,
+                        DELETE_JOB_DELAY);
+                showDeleteSnackbar(hidden, operationId);
+            }
+        }.execute(selected);
     }
 
     private void showDeleteSnackbar(final SparseArray<String> hidden, final String jobId) {
@@ -834,6 +857,19 @@
         }.execute(selected);
     }
 
+    private void renameDocuments(Selection selected) {
+        // Batch renaming not supported
+        // Rename option is only available in menu when 1 document selected
+        checkArgument(selected.size() == 1);
+
+        new GetDocumentsTask() {
+            @Override
+            void onDocumentsReady(List<DocumentInfo> docs) {
+                RenameDocumentFragment.show(getFragmentManager(), docs.get(0));
+            }
+        }.execute(selected);
+    }
+
     @Override
     public void initDocumentHolder(DocumentHolder holder) {
         holder.addEventListener(mItemEventListener);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index ef6d2c9..a295ab2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -58,7 +58,8 @@
     }
 
 
-    public abstract void updateActionMenu(Menu menu, int dirType, boolean canDelete);
+    public abstract void updateActionMenu(Menu menu, int dirType, boolean canDelete,
+            boolean canRename);
 
     // Subtly different from isDocumentEnabled. The reason may be illuminated as follows.
     // A folder is enabled such that it may be double clicked, even in settings
@@ -129,7 +130,8 @@
         }
 
         @Override
-        public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+        public void updateActionMenu(Menu menu, int dirType, boolean canDelete,
+                boolean canRename) {
 
             boolean copyEnabled = dirType != DirectoryFragment.TYPE_RECENT_OPEN;
             boolean moveEnabled =
@@ -141,6 +143,7 @@
             final MenuItem delete = menu.findItem(R.id.menu_delete);
             final MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
             final MenuItem moveTo = menu.findItem(R.id.menu_move_to);
+            final MenuItem rename = menu.findItem(R.id.menu_rename);
 
             open.setVisible(true);
             share.setVisible(false);
@@ -149,6 +152,7 @@
             copyTo.setEnabled(copyEnabled);
             moveTo.setVisible(moveEnabled);
             moveTo.setEnabled(moveEnabled);
+            rename.setVisible(false);
         }
     }
 
@@ -162,7 +166,8 @@
         }
 
         @Override
-        public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+        public void updateActionMenu(Menu menu, int dirType, boolean canDelete,
+                boolean canRename) {
             checkArgument(dirType != DirectoryFragment.TYPE_RECENT_OPEN);
 
             boolean moveEnabled =
@@ -174,6 +179,7 @@
             final MenuItem delete = menu.findItem(R.id.menu_delete);
             final MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
             final MenuItem moveTo = menu.findItem(R.id.menu_move_to);
+            final MenuItem rename = menu.findItem(R.id.menu_rename);
 
             open.setVisible(false);
             delete.setVisible(canDelete);
@@ -181,6 +187,7 @@
             copyTo.setEnabled(true);
             moveTo.setVisible(moveEnabled);
             moveTo.setEnabled(moveEnabled);
+            rename.setVisible(false);
         }
     }
 
@@ -194,12 +201,17 @@
         }
 
         @Override
-        public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+        public void updateActionMenu(Menu menu, int dirType, boolean canDelete,
+                boolean canRename) {
 
             MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard);
             MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard);
             copy.setEnabled(dirType != DirectoryFragment.TYPE_RECENT_OPEN);
 
+            MenuItem rename = menu.findItem(R.id.menu_rename);
+            rename.setVisible(true);
+            rename.setEnabled(canRename);
+
             menu.findItem(R.id.menu_share).setVisible(true);
             menu.findItem(R.id.menu_delete).setVisible(canDelete);
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
new file mode 100644
index 0000000..71708c1
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 static com.android.documentsui.Shared.TAG;
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.android.documentsui.BaseActivity;
+import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.R;
+import com.android.documentsui.Snackbars;
+/**
+ * Dialog to rename file or directory.
+ */
+class RenameDocumentFragment extends DialogFragment {
+    private static final String TAG_RENAME_DOCUMENT = "rename_document";
+    private DocumentInfo mDocument;
+
+    public static void show(FragmentManager fm, DocumentInfo document) {
+        final RenameDocumentFragment dialog = new RenameDocumentFragment();
+        dialog.mDocument = document;
+        dialog.show(fm, TAG_RENAME_DOCUMENT);
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Context context = getActivity();
+        AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
+        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);
+
+        builder.setTitle(R.string.menu_rename);
+        builder.setView(view);
+
+        builder.setPositiveButton(
+                android.R.string.ok,
+                new OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        renameDocuments(editText.getText().toString());
+                    }
+                });
+
+        builder.setNegativeButton(android.R.string.cancel, null);
+
+        final AlertDialog dialog = builder.create();
+
+        editText.setOnEditorActionListener(
+                new OnEditorActionListener() {
+                    @Override
+                    public boolean onEditorAction(
+                            TextView view, int actionId, @Nullable KeyEvent event) {
+                        if (event != null
+                                && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
+                                && event.hasNoModifiers()) {
+                            renameDocuments(editText.getText().toString());
+                            dialog.dismiss();
+                            return true;
+                        }
+                        return false;
+                    }
+                });
+
+        return dialog;
+    }
+
+    private void renameDocuments(String newDisplayName) {
+        BaseActivity activity = (BaseActivity) getActivity();
+
+        new RenameDocumentsTask(activity, newDisplayName).execute(mDocument);
+    }
+
+    private class RenameDocumentsTask extends AsyncTask<DocumentInfo, Void, DocumentInfo> {
+        private final BaseActivity mActivity;
+        private final String mNewDisplayName;
+
+        public RenameDocumentsTask(BaseActivity activity, String newDisplayName) {
+            mActivity = activity;
+            mNewDisplayName = newDisplayName;
+        }
+
+        @Override
+        protected void onPreExecute() {
+            mActivity.setPending(true);
+        }
+
+        @Override
+        protected DocumentInfo doInBackground(DocumentInfo... document) {
+            checkArgument(document.length == 1);
+            final ContentResolver resolver = mActivity.getContentResolver();
+            ContentProviderClient client = null;
+
+            try {
+                client = DocumentsApplication.acquireUnstableProviderOrThrow(
+                        resolver, document[0].derivedUri.getAuthority());
+                Uri newUri = DocumentsContract.renameDocument(
+                        client, document[0].derivedUri, mNewDisplayName);
+                return DocumentInfo.fromUri(resolver, newUri);
+            } catch (Exception e) {
+                Log.w(TAG, "Failed to rename file", e);
+                return null;
+            } finally {
+                ContentProviderClient.releaseQuietly(client);
+            }
+        }
+
+        @Override
+        protected void onPostExecute(DocumentInfo result) {
+            if (result == null) {
+                Snackbars.makeSnackbar(mActivity, R.string.rename_error, Snackbar.LENGTH_SHORT)
+                        .show();
+            }
+
+            mActivity.setPending(false);
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 83df18c..4b5499a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -239,6 +239,10 @@
         return (flags & Document.FLAG_SUPPORTS_DELETE) != 0;
     }
 
+    public boolean isRenameSupported() {
+        return (flags & Document.FLAG_SUPPORTS_RENAME) != 0;
+    }
+
     public boolean isGridTitlesHidden() {
         return (flags & Document.FLAG_DIR_HIDE_GRID_TITLES) != 0;
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
index f3195a7..1d8eba5 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
@@ -199,7 +199,7 @@
                     "Copying " + srcInfo.displayName + " (" + srcInfo.derivedUri + ")"
                     + " to " + dstInfo.displayName + " (" + dstInfo.derivedUri + ")");
 
-            processDocument(srcInfo, dstInfo);
+            processDocument(srcInfo, null, dstInfo);
         }
     }
 
@@ -220,11 +220,15 @@
      * Copies a the given document to the given location.
      *
      * @param src DocumentInfos for the documents to copy.
+     * @param srcParent DocumentInfo for the parent of the document to process.
      * @param dstDirInfo The destination directory.
      * @return True on success, false on failure.
      * @throws RemoteException
+     *
+     * TODO: Stop passing srcParent, as it's not used for copy, but for move only.
      */
-    boolean processDocument(DocumentInfo src, DocumentInfo dstDirInfo) throws RemoteException {
+    boolean processDocument(DocumentInfo src, DocumentInfo srcParent,
+            DocumentInfo dstDirInfo) throws RemoteException {
 
         // TODO: When optimized copy kicks in, we'll not making any progress updates.
         // For now. Local storage isn't using optimized copy.
@@ -332,7 +336,7 @@
             cursor = getClient(srcDir).query(queryUri, queryColumns, null, null, null);
             while (cursor.moveToNext() && !isCanceled()) {
                 DocumentInfo src = DocumentInfo.fromCursor(cursor, srcDir.authority);
-                success &= processDocument(src, destDir);
+                success &= processDocument(src, srcDir, destDir);
             }
         } finally {
             IoUtils.closeQuietly(cursor);
@@ -509,7 +513,7 @@
                 .append("CopyJob")
                 .append("{")
                 .append("id=" + id)
-                .append("srcs=" + mSrcs)
+                .append(", srcs=" + mSrcs)
                 .append(", destination=" + stack)
                 .append("}")
                 .toString();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java
index 6a2a794..eef696a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java
@@ -35,6 +35,7 @@
 
     private static final String TAG = "DeleteJob";
     private List<DocumentInfo> mSrcs;
+    final DocumentInfo mSrcParent;
 
     /**
      * Moves files to a destination identified by {@code destination}.
@@ -43,12 +44,14 @@
      *
      * @see @link {@link Job} constructor for most param descriptions.
      *
-     * @param srcs List of files to delete
+     * @param srcs List of files to delete.
+     * @param srcParent Parent of all source files.
      */
     DeleteJob(Context service, Context appContext, Listener listener,
-            String id, DocumentStack stack, List<DocumentInfo> srcs) {
+            String id, DocumentStack stack, List<DocumentInfo> srcs, DocumentInfo srcParent) {
         super(service, appContext, listener, OPERATION_DELETE, id, stack);
         this.mSrcs = srcs;
+        this.mSrcParent = srcParent;
     }
 
     @Override
@@ -75,6 +78,8 @@
     void start() throws RemoteException {
         for (DocumentInfo doc : mSrcs) {
             if (DEBUG) Log.d(TAG, "Deleting document @ " + doc.derivedUri);
+            // TODO: Start using mSrcParent as soon as DocumentsProvider::removeDocument() is
+            // implemented.
             if (!deleteDocument(doc)) {
                 Log.w(TAG, "Failed to delete document @ " + doc.derivedUri);
                 onFileFailed(doc);
@@ -88,7 +93,8 @@
                 .append("DeleteJob")
                 .append("{")
                 .append("id=" + id)
-                .append("srcs=" + mSrcs)
+                .append(", srcs=" + mSrcs)
+                .append(", srcParent=" + mSrcParent)
                 .append(", location=" + stack)
                 .append("}")
                 .toString();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
index aca2d7a..5d74cdc 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
@@ -65,6 +65,11 @@
     public static final String EXTRA_SRC_LIST = "com.android.documentsui.SRC_LIST";
     public static final String EXTRA_FAILURE = "com.android.documentsui.FAILURE";
 
+    // This extra is used only for moving and deleting. Currently it's not the case,
+    // but in the future those files may be from multiple different parents. In
+    // 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;
@@ -152,14 +157,14 @@
         Job job = null;
         synchronized (mRunning) {
             if (mWakeLock == null) {
-                mWakeLock = mPowerManager.newWakeLock(
-                        PowerManager.PARTIAL_WAKE_LOCK, TAG);
+                mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
             }
 
             List<DocumentInfo> srcs = intent.getParcelableArrayListExtra(EXTRA_SRC_LIST);
+            DocumentInfo srcParent = intent.getParcelableExtra(EXTRA_SRC_PARENT);
             DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
 
-            job = createJob(operationType, jobId, srcs, stack);
+            job = createJob(operationType, jobId, srcs, srcParent, stack);
 
             if (job == null) {
                 return;
@@ -222,7 +227,8 @@
      */
     @GuardedBy("mRunning")
     private @Nullable Job createJob(
-            @OpType int operationType, String id, List<DocumentInfo> srcs, DocumentStack stack) {
+            @OpType int operationType, String id, List<DocumentInfo> srcs, DocumentInfo srcParent,
+            DocumentStack stack) {
 
         if (mRunning.containsKey(id)) {
             Log.w(TAG, "Duplicate job id: " + id
@@ -236,10 +242,12 @@
                 job = jobFactory.createCopy(this, getApplicationContext(), this, id, stack, srcs);
                 break;
             case OPERATION_MOVE:
-                job = jobFactory.createMove(this, getApplicationContext(), this, id, stack, srcs);
+                job = jobFactory.createMove(this, getApplicationContext(), this, id, stack, srcs,
+                        srcParent);
                 break;
             case OPERATION_DELETE:
-                job = jobFactory.createDelete(this, getApplicationContext(), this, id, stack, srcs);
+                job = jobFactory.createDelete(this, getApplicationContext(), this, id, stack, srcs,
+                        srcParent);
                 break;
             default:
                 throw new UnsupportedOperationException();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
index f59a32a..9d017ee 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
@@ -26,6 +26,7 @@
 import static com.android.documentsui.services.FileOperationService.EXTRA_JOB_ID;
 import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION;
 import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_LIST;
+import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_PARENT;
 import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
 import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
 import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
@@ -35,6 +36,7 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.os.Parcelable;
+import android.support.annotation.VisibleForTesting;
 import android.support.design.widget.Snackbar;
 import android.util.Log;
 
@@ -65,8 +67,8 @@
      * Tries to start the activity. Returns the job id.
      */
     public static String start(
-            Activity activity, List<DocumentInfo> srcDocs, DocumentStack stack,
-            int operationType) {
+            Activity activity, List<DocumentInfo> srcDocs,
+            DocumentStack stack, int operationType) {
 
         if (DEBUG) Log.d(TAG, "Handling generic 'start' call.");
 
@@ -74,7 +76,7 @@
             case OPERATION_COPY:
                 return FileOperations.copy(activity, srcDocs, stack);
             case OPERATION_MOVE:
-                return FileOperations.move(activity, srcDocs, stack);
+                throw new IllegalArgumentException("Moving requires providing the source parent.");
             case OPERATION_DELETE:
                 throw new UnsupportedOperationException("Delete isn't currently supported.");
             default:
@@ -83,14 +85,27 @@
     }
 
     /**
-     * Makes a best effort to cancel operation identified by jobId.
-     *
-     * @param context Context for the intent.
-     * @param jobId The id of the job to cancel.
-     *     Use {@link #createJobId} if you don't have one handy.
-     * @param srcDocs A list of src files to copy.
-     * @param dstStack The copy destination stack.
+     * Tries to start the activity. Returns the job id.
      */
+    public static String start(
+            Activity activity, List<DocumentInfo> srcDocs, DocumentInfo srcParent,
+            DocumentStack stack, int operationType) {
+
+        if (DEBUG) Log.d(TAG, "Handling generic 'start' call.");
+
+        switch (operationType) {
+            case OPERATION_COPY:
+                return FileOperations.copy(activity, srcDocs, stack);
+            case OPERATION_MOVE:
+                return FileOperations.move(activity, srcDocs, srcParent, stack);
+            case OPERATION_DELETE:
+                throw new UnsupportedOperationException("Delete isn't currently supported.");
+            default:
+                throw new UnsupportedOperationException("Unknown operation: " + operationType);
+        }
+    }
+
+    @VisibleForTesting
     public static void cancel(Activity activity, String jobId) {
         if (DEBUG) Log.d(TAG, "Attempting to canceling operation: " + jobId);
 
@@ -101,15 +116,7 @@
         activity.startService(intent);
     }
 
-    /**
-     * Starts the service for a copy operation.
-     *
-     * @param context Context for the intent.
-     * @param jobId A unique jobid for this job.
-     *     Use {@link #createJobId} if you don't have one handy.
-     * @param srcDocs A list of src files to copy.
-     * @param destination The copy destination stack.
-     */
+    @VisibleForTesting
     public static String copy(
             Activity activity, List<DocumentInfo> srcDocs, DocumentStack destination) {
         String jobId = createJobId();
@@ -131,14 +138,17 @@
      * @param jobId A unique jobid for this job.
      *     Use {@link #createJobId} if you don't have one handy.
      * @param srcDocs A list of src files to copy.
+     * @param srcParent Parent of all the source documents.
      * @param destination The move destination stack.
      */
     public static String move(
-            Activity activity, List<DocumentInfo> srcDocs, DocumentStack destination) {
+            Activity activity, List<DocumentInfo> srcDocs, DocumentInfo srcParent,
+            DocumentStack destination) {
         String jobId = createJobId();
         if (DEBUG) Log.d(TAG, "Initiating 'move' operation id: " + jobId);
 
-        Intent intent = createBaseIntent(OPERATION_MOVE, activity, jobId, srcDocs, destination);
+        Intent intent = createBaseIntent(OPERATION_MOVE, activity, jobId, srcDocs, srcParent,
+                destination);
 
         createSharedSnackBar(activity, R.plurals.move_begin, srcDocs.size())
                 .show();
@@ -154,16 +164,19 @@
      * @param jobId A unique jobid for this job.
      *     Use {@link #createJobId} if you don't have one handy.
      * @param srcDocs A list of src files to copy.
+     * @param srcParent Parent of all the source documents.
      * @param delay Number of milliseconds to wait before executing the job.
      * @return Id of the job.
      */
     public static String delete(
-            Activity activity, List<DocumentInfo> srcDocs, DocumentStack location, int delay) {
+            Activity activity, List<DocumentInfo> srcDocs, DocumentInfo srcParent,
+            DocumentStack location, int delay) {
         String jobId = createJobId();
         if (DEBUG) Log.d(TAG, "Initiating 'delete' operation id " + jobId
                 + " delayed by " + delay + " milliseconds.");
 
-        Intent intent = createBaseIntent(OPERATION_DELETE, activity, jobId, srcDocs, location);
+        Intent intent = createBaseIntent(OPERATION_DELETE, activity, jobId, srcDocs, srcParent,
+                location);
         intent.putExtra(EXTRA_DELAY, delay);
         activity.startService(intent);
 
@@ -171,7 +184,7 @@
     }
 
     /**
-     * Starts the service for a move operation.
+     * Starts the service for an operation.
      *
      * @param jobId A unique jobid for this job.
      *     Use {@link #createJobId} if you don't have one handy.
@@ -179,13 +192,35 @@
      * @return Id of the job.
      */
     public static Intent createBaseIntent(
-            @OpType int operationType, Context context, String jobId,
-            List<DocumentInfo> srcDocs, DocumentStack localeStack) {
+            @OpType int operationType, Context context, String jobId, List<DocumentInfo> srcDocs,
+            DocumentStack localeStack) {
 
         Intent intent = new Intent(context, FileOperationService.class);
         intent.putExtra(EXTRA_JOB_ID, jobId);
-        intent.putParcelableArrayListExtra(
-                EXTRA_SRC_LIST, asArrayList(srcDocs));
+        intent.putParcelableArrayListExtra(EXTRA_SRC_LIST, asArrayList(srcDocs));
+        intent.putExtra(EXTRA_STACK, (Parcelable) localeStack);
+        intent.putExtra(EXTRA_OPERATION, operationType);
+
+        return intent;
+    }
+
+    /**
+     * Starts the service for an operation.
+     *
+     * @param jobId A unique jobid for this job.
+     *     Use {@link #createJobId} if you don't have one handy.
+     * @param srcDocs A list of src files to copy.
+     * @param srcParent Parent of all the source documents.
+     * @return Id of the job.
+     */
+    public static Intent createBaseIntent(
+            @OpType int operationType, Context context, String jobId,
+            List<DocumentInfo> srcDocs, DocumentInfo srcParent, DocumentStack localeStack) {
+
+        Intent intent = new Intent(context, FileOperationService.class);
+        intent.putExtra(EXTRA_JOB_ID, jobId);
+        intent.putParcelableArrayListExtra(EXTRA_SRC_LIST, asArrayList(srcDocs));
+        intent.putExtra(EXTRA_SRC_PARENT, srcParent);
         intent.putExtra(EXTRA_STACK, (Parcelable) localeStack);
         intent.putExtra(EXTRA_OPERATION, operationType);
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
index f351df9..9534d6c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
@@ -274,13 +274,15 @@
         }
 
         Job createMove(Context service, Context appContext, Listener listener,
-                String id, DocumentStack stack, List<DocumentInfo> srcs) {
-            return new MoveJob(service, appContext, listener, id, stack, srcs);
+                String id, DocumentStack stack, List<DocumentInfo> srcs,
+                DocumentInfo srcParent) {
+            return new MoveJob(service, appContext, listener, id, stack, srcs, srcParent);
         }
 
         Job createDelete(Context service, Context appContext, Listener listener,
-                String id, DocumentStack stack, List<DocumentInfo> srcs) {
-            return new DeleteJob(service, appContext, listener, id, stack, srcs);
+                String id, DocumentStack stack, List<DocumentInfo> srcs,
+                DocumentInfo srcParent) {
+            return new DeleteJob(service, appContext, listener, id, stack, srcs, srcParent);
         }
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
index 7a238bd..9b72077 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
@@ -21,6 +21,7 @@
 import android.app.Notification;
 import android.app.Notification.Builder;
 import android.content.Context;
+import android.net.Uri;
 import android.os.RemoteException;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
@@ -32,9 +33,11 @@
 
 import java.util.List;
 
+// TODO: Stop extending CopyJob.
 final class MoveJob extends CopyJob {
 
     private static final String TAG = "MoveJob";
+    final DocumentInfo mSrcParent;
 
     /**
      * Moves files to a destination identified by {@code destination}.
@@ -44,10 +47,12 @@
      * @see @link {@link Job} constructor for most param descriptions.
      *
      * @param srcs List of files to be moved.
+     * @param srcParent Parent of all source files.
      */
     MoveJob(Context service, Context appContext, Listener listener,
-            String id, DocumentStack destination, List<DocumentInfo> srcs) {
+            String id, DocumentStack destination, List<DocumentInfo> srcs, DocumentInfo srcParent) {
         super(service, appContext, listener, OPERATION_MOVE, id, destination, srcs);
+        this.mSrcParent = srcParent;
     }
 
     @Override
@@ -75,8 +80,8 @@
                 R.plurals.move_error_notification_title, R.drawable.ic_menu_copy);
     }
 
-    @Override
-    boolean processDocument(DocumentInfo src, DocumentInfo dest) throws RemoteException {
+    boolean processDocument(DocumentInfo src, DocumentInfo srcParent, DocumentInfo dest)
+            throws RemoteException {
 
         // TODO: When optimized move kicks in, we're not making any progress updates. FIX IT!
 
@@ -85,6 +90,7 @@
         if (src.authority.equals(dest.authority)) {
             if ((src.flags & Document.FLAG_SUPPORTS_MOVE) != 0) {
                 if (DocumentsContract.moveDocument(getClient(src), src.derivedUri,
+                        srcParent != null ? srcParent.derivedUri : mSrcParent.derivedUri,
                         dest.derivedUri) == null) {
                     onFileFailed(src);
                     return false;
@@ -105,6 +111,7 @@
         // If we couldn't do an optimized copy...we fall back to vanilla byte copy.
         boolean copied = byteCopyDocument(src, dest);
 
+        // TODO: Replace deleteDocument() with removeDocument() once implemented.
         return copied && !isCanceled() && deleteDocument(src);
     }
 
@@ -114,7 +121,8 @@
                 .append("MoveJob")
                 .append("{")
                 .append("id=" + id)
-                .append("srcs=" + mSrcs)
+                .append(", srcs=" + mSrcs)
+                .append(", srcParent=" + mSrcParent)
                 .append(", destination=" + stack)
                 .append("}")
                 .toString();
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java
index 3c40b67..467d97e 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java
@@ -20,6 +20,7 @@
 import static android.provider.DocumentsContract.buildDocumentUri;
 import static android.provider.DocumentsContract.buildRootsUri;
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
+import static com.android.internal.util.Preconditions.checkArgument;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.fail;
@@ -37,7 +38,7 @@
 import android.provider.DocumentsContract.Root;
 import android.support.annotation.Nullable;
 import android.test.MoreAsserts;
-import android.util.Log;
+import android.text.TextUtils;
 
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.RootInfo;
@@ -60,13 +61,13 @@
     private final ContentProviderClient mClient;
 
     public DocumentsProviderHelper(String authority, ContentProviderClient client) {
+        checkArgument(!TextUtils.isEmpty(authority));
         mAuthority = authority;
         mClient = client;
     }
 
     public RootInfo getRoot(String documentId) throws RemoteException {
         final Uri rootsUri = buildRootsUri(mAuthority);
-
         Cursor cursor = null;
         try {
             cursor = mClient.query(rootsUri, null, null, null, null);
@@ -126,7 +127,6 @@
     }
 
     public byte[] readDocument(Uri documentUri) throws RemoteException, IOException {
-        Log.d("DocumentsProviderHelper", "Trying to read file contents: " + documentUri);
         ParcelFileDescriptor file = mClient.openFile(documentUri, "r", null);
         byte[] buf = null;
         try (AutoCloseInputStream in = new AutoCloseInputStream(file)) {
@@ -245,21 +245,18 @@
         Uri uri = buildChildDocumentsUri(mAuthority, documentId);
         List<DocumentInfo> children = new ArrayList<>();
         try (Cursor cursor = mClient.query(uri, null, null, null, null, null)) {
-            while (cursor.moveToNext()) {
-                children.add(DocumentInfo.fromDirectoryCursor(cursor));
+            Cursor wrapper = new RootCursorWrapper(mAuthority, "totally-fake", cursor, 100);
+            while (wrapper.moveToNext()) {
+                children.add(DocumentInfo.fromDirectoryCursor(wrapper));
             }
         }
         return children;
     }
 
     public void assertFileContents(Uri documentUri, byte[] expected) throws Exception {
-        // TODO: Fix this: java.lang.SecurityException:
-        // The authority of the uri content:/document/%2Fdata%2Fuser%2F0%2Fcom.android.documentsui.\
-        // tests%2Fcache%2FTEST_ROOT_1%2Ftest1.txt does not match the one of the contentProvider: \
-        // com.android.documentsui.stubprovider
-//        MoreAsserts.assertEquals(
-//                "Copied file contents differ",
-//                expected, readDocument(documentUri));
+        MoreAsserts.assertEquals(
+                "Copied file contents differ",
+                expected, readDocument(documentUri));
     }
 
     public void assertFileContents(String parentId, String fileName, byte[] expected)
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
index 1b8bd4e..6c9c5d9 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
@@ -223,7 +223,8 @@
 
         assertFalse(mDocsList.exists());
         assertTrue(mMessageTextView.exists());
-        assertEquals(mContext.getString(R.string.empty), mMessageTextView.getText());
+        String msg = String.valueOf(mContext.getString(R.string.no_results));
+        assertEquals(String.format(msg, "TEST_ROOT_0"), mMessageTextView.getText());
         assertSearchTextField(false, query);
     }
 
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
index a47d350..cc48786 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
@@ -660,7 +660,7 @@
             this.documentId = getDocumentIdForFile(file);
             this.mimeType = Document.MIME_TYPE_DIR;
             this.streamTypes = new ArrayList<String>();
-            this.flags = Document.FLAG_DIR_SUPPORTS_CREATE;
+            this.flags = Document.FLAG_DIR_SUPPORTS_CREATE | Document.FLAG_SUPPORTS_RENAME;
             this.parentId = null;
             this.rootInfo = rootInfo;
         }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java
index ec21150..eb8a061 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java
@@ -23,6 +23,7 @@
 import android.test.suitebuilder.annotation.MediumTest;
 
 import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
 
 import java.util.List;
 
@@ -109,7 +110,9 @@
     public void runNoCopyDirToSelfTest() throws Exception {
         Uri testDir = mDocs.createFolder(mSrcRoot, "someDir");
 
-        createJob(newArrayList(testDir), testDir).run();
+        createJob(newArrayList(testDir),
+                DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId),
+                testDir).run();
 
         mJobListener.waitForFinished();
         mJobListener.assertFailed();
@@ -122,7 +125,9 @@
         Uri testDir = mDocs.createFolder(mSrcRoot, "someDir");
         Uri destDir = mDocs.createFolder(testDir, "theDescendent");
 
-        createJob(newArrayList(testDir), destDir).run();
+        createJob(newArrayList(testDir),
+                DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId),
+                destDir).run();
 
         mJobListener.waitForFinished();
         mJobListener.assertFailed();
@@ -148,10 +153,13 @@
     }
 
     /**
-     * Creates a job with a stack consisting to the default destination.
+     * Creates a job with a stack consisting to the default source and destination.
+     * TODO: Clean up, as mDestRoot.documentInfo may not really be the parent of
+     * srcs.
      */
     final T createJob(List<Uri> srcs) throws Exception {
+        Uri srcParent = DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId);
         Uri destination = DocumentsContract.buildDocumentUri(AUTHORITY, mDestRoot.documentId);
-        return createJob(srcs, destination);
+        return createJob(srcs, srcParent, destination);
     }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java
index 691af6a..e559503 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java
@@ -85,7 +85,7 @@
         mDestRoot = mDocs.getRoot(ROOT_1_ID);
     }
 
-    final T createJob(List<Uri> srcs, Uri destination) throws Exception {
+    final T createJob(List<Uri> srcs, Uri srcParent, Uri destination) throws Exception {
         DocumentStack stack = new DocumentStack();
         stack.push(DocumentInfo.fromUri(mResolver, destination));
 
@@ -94,8 +94,9 @@
             srcDocs.add(DocumentInfo.fromUri(mResolver, src));
         }
 
-        return createJob(srcDocs, stack);
+        return createJob(srcDocs, DocumentInfo.fromUri(mResolver, srcParent), stack);
     }
 
-    abstract T createJob(List<DocumentInfo> srcs, DocumentStack destination) throws Exception;
+    abstract T createJob(List<DocumentInfo> srcs, DocumentInfo srcParent, DocumentStack destination)
+            throws Exception;
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java
index 1acf2dc..543396e 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java
@@ -59,7 +59,9 @@
     }
 
     @Override
-    CopyJob createJob(List<DocumentInfo> srcs, DocumentStack stack) throws Exception {
+    // TODO: Stop passing srcParent here, as it's not used for copying.
+    CopyJob createJob(List<DocumentInfo> srcs, DocumentInfo srcParent, DocumentStack stack)
+            throws Exception {
         return new CopyJob(
                 mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs);
     }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java
index d6d10239..722df75 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java
@@ -37,7 +37,8 @@
         Uri testFile2 = mDocs.createDocument(mSrcRoot, "text/plain", "test2.txt");
         mDocs.writeDocument(testFile2, FRUITY_BYTES);
 
-        createJob(newArrayList(testFile1, testFile2)).run();
+        createJob(newArrayList(testFile1, testFile2),
+                DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId)).run();
         mJobListener.waitForFinished();
 
         mDocs.assertChildCount(mSrcRoot, 0);
@@ -46,14 +47,17 @@
     /**
      * Creates a job with a stack consisting to the default src directory.
      */
-    private final DeleteJob createJob(List<Uri> srcs) throws Exception {
+    private final DeleteJob createJob(List<Uri> srcs, Uri srcParent) throws Exception {
         Uri stack = DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId);
-        return createJob(srcs, stack);
+        return createJob(srcs, srcParent, stack);
     }
 
     @Override
-    DeleteJob createJob(List<DocumentInfo> srcs, DocumentStack stack) throws Exception {
+    // TODO: Remove inheritance, as stack is not used for deleting, nor srcParent.
+    DeleteJob createJob(List<DocumentInfo> srcs, DocumentInfo srcParent, DocumentStack stack)
+            throws Exception {
         return new DeleteJob(
-                mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs);
+                mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs,
+                srcParent);
     }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java
index 69d2db7..749264a 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java
@@ -19,6 +19,8 @@
 import static com.google.common.collect.Lists.newArrayList;
 
 import android.net.Uri;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract;
 import android.test.suitebuilder.annotation.MediumTest;
 
 import com.android.documentsui.model.DocumentInfo;
@@ -36,8 +38,9 @@
     }
 
     public void testMoveVirtualTypedFile() throws Exception {
+        mDocs.createFolder(mSrcRoot, "hello");
         Uri testFile = mDocs.createVirtualFile(
-                mSrcRoot, "/virtual.sth", "virtual/mime-type",
+                mSrcRoot, "/hello/virtual.sth", "virtual/mime-type",
                 FRUITY_BYTES, "application/pdf", "text/html");
         createJob(newArrayList(testFile)).run();
 
@@ -89,9 +92,13 @@
         mDocs.assertChildCount(mSrcRoot, 1);
     }
 
+    // TODO: Add test cases for moving when multi-parented.
+
     @Override
-    MoveJob createJob(List<DocumentInfo> srcs, DocumentStack stack) throws Exception {
+    MoveJob createJob(List<DocumentInfo> srcs, DocumentInfo srcParent, DocumentStack stack)
+            throws Exception {
         return new MoveJob(
-                mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs);
+                mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs,
+                srcParent);
     }
 }
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index c6e5531..1bfc19c 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -25,6 +25,7 @@
 import android.database.MatrixCursor.RowBuilder;
 import android.graphics.Point;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.FileObserver;
 import android.os.FileUtils;
@@ -234,7 +235,13 @@
         return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION;
     }
 
+
     private String getDocIdForFile(File file) throws FileNotFoundException {
+        return getDocIdForFileMaybeCreate(file, false);
+    }
+
+    private String getDocIdForFileMaybeCreate(File file, boolean createNewDir)
+            throws FileNotFoundException {
         String path = file.getAbsolutePath();
 
         // Find the most-specific root path
@@ -266,6 +273,13 @@
             path = path.substring(rootPath.length() + 1);
         }
 
+        if (!file.exists() && createNewDir) {
+            Log.i(TAG, "Creating new directory " + file);
+            if (!file.mkdir()) {
+                Log.e(TAG, "Could not create directory " + file);
+            }
+        }
+
         return mostSpecificId + ':' + path;
     }
 
@@ -463,7 +477,8 @@
     }
 
     @Override
-    public String moveDocument(String sourceDocumentId, String targetParentDocumentId)
+    public String moveDocument(String sourceDocumentId, String sourceParentDocumentId,
+            String targetParentDocumentId)
             throws FileNotFoundException {
         final File before = getFileForDocId(sourceDocumentId);
         final File after = new File(getFileForDocId(targetParentDocumentId), before.getName());
@@ -608,6 +623,34 @@
         }
     }
 
+    @Override
+    public Bundle call(String method, String arg, Bundle extras) {
+        Bundle bundle = super.call(method, arg, extras);
+        if (bundle == null && !TextUtils.isEmpty(method)) {
+            switch (method) {
+                case "getDocIdForFileCreateNewDir": {
+                    getContext().enforceCallingPermission(
+                            android.Manifest.permission.MANAGE_DOCUMENTS, null);
+                    if (TextUtils.isEmpty(arg)) {
+                        return null;
+                    }
+                    try {
+                        final String docId = getDocIdForFileMaybeCreate(new File(arg), true);
+                        bundle = new Bundle();
+                        bundle.putString("DOC_ID", docId);
+                    } catch (FileNotFoundException e) {
+                        Log.w(TAG, "file '" + arg + "' not found");
+                        return null;
+                    }
+                    break;
+                }
+                default:
+                    Log.w(TAG, "unknown method passed to call(): " + method);
+            }
+        }
+        return bundle;
+    }
+
     private static String getTypeForFile(File file) {
         if (file.isDirectory()) {
             return Document.MIME_TYPE_DIR;
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
index cbf22c0..40c11cf 100644
--- a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
@@ -29,6 +29,7 @@
 import android.widget.Button;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.widget.LockPatternUtils;
 
@@ -117,7 +118,7 @@
      * Shows the emergency dialer or returns the user to the existing call.
      */
     public void takeEmergencyCallAction() {
-        MetricsLogger.action(mContext, MetricsLogger.ACTION_EMERGENCY_CALL);
+        MetricsLogger.action(mContext, MetricsEvent.ACTION_EMERGENCY_CALL);
         // TODO: implement a shorter timeout once new PowerManager API is ready.
         // should be the equivalent to the old userActivity(EMERGENCY_CALL_TIMEOUT)
         mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
index 3a7e6d0..63dec8b 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -117,8 +117,10 @@
                 return R.string.kg_prompt_reason_restart_password;
             case PROMPT_REASON_TIMEOUT:
                 return R.string.kg_prompt_reason_timeout_password;
-            default:
+            case PROMPT_REASON_NONE:
                 return 0;
+            default:
+                return R.string.kg_prompt_reason_timeout_password;
         }
     }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 2a2f5a0..be2701d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -339,7 +339,11 @@
                 mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern,
                         true /* important */);
                 break;
+            case PROMPT_REASON_NONE:
+                break;
             default:
+                mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern,
+                        true /* important */);
                 break;
         }
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
index f51e10f..cedd88d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -103,8 +103,10 @@
                 return R.string.kg_prompt_reason_restart_pin;
             case PROMPT_REASON_TIMEOUT:
                 return R.string.kg_prompt_reason_timeout_pin;
-            default:
+            case PROMPT_REASON_NONE:
                 return 0;
+            default:
+                return R.string.kg_prompt_reason_timeout_pin;
         }
     }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
index 38302fb..aa74940 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
@@ -34,6 +34,26 @@
     int PROMPT_REASON_TIMEOUT = 2;
 
     /**
+     * Strong auth is required because a device admin requested it.
+     */
+    int PROMPT_REASON_DEVICE_ADMIN = 3;
+
+    /**
+     * Some auth is required because the user force locked.
+     */
+    int PROMPT_REASON_USER_REQUEST = 4;
+
+    /**
+     * Some auth is required because too many wrong credentials led to a lockout.
+     */
+    int PROMPT_REASON_AFTER_LOCKOUT = 5;
+
+    /**
+     * Some auth is required because a single wrong credential has been tried.
+     */
+    int PROMPT_REASON_WRONG_CREDENTIAL = 6;
+
+    /**
      * Interface back to keyguard to tell it when security
      * @param callback
      */
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index b4f9b9f..a8419bf 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -188,7 +188,7 @@
 
     /** Tracks whether strong authentication hasn't been used since quite some time per user. */
     private ArraySet<Integer> mStrongAuthNotTimedOut = new ArraySet<>();
-    private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker();
+    private final StrongAuthTracker mStrongAuthTracker;
 
     private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
             mCallbacks = Lists.newArrayList();
@@ -871,6 +871,9 @@
     }
 
     public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
+        public StrongAuthTracker(Context context) {
+            super(context);
+        }
 
         public boolean isUnlockingWithFingerprintAllowed() {
             int userId = getCurrentUser();
@@ -981,6 +984,7 @@
         mSubscriptionManager = SubscriptionManager.from(context);
         mAlarmManager = context.getSystemService(AlarmManager.class);
         mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
+        mStrongAuthTracker = new StrongAuthTracker(context);
 
         // Since device can't be un-provisioned, we only need to register a content observer
         // to update mDeviceProvisioned when we are...
diff --git a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
index 66a3247..7b57d89 100644
--- a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
+++ b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
@@ -332,23 +332,20 @@
             uint64_t offset,
             uint32_t size,
             void* buf) {
-        const uint32_t read_size = static_cast<uint32_t>(std::min(
-                static_cast<uint64_t>(size),
-                get_file_size(inode) - offset));
         ScopedLocalRef<jbyteArray> array(env_, static_cast<jbyteArray>(env_->CallObjectMethod(
                 self_,
                 app_fuse_get_object_bytes,
                 inode,
                 offset,
-                read_size)));
+                size)));
         if (array.get() == nullptr) {
             return -1;
         }
         ScopedByteArrayRO bytes(env_, array.get());
-        if (bytes.size() != read_size || bytes.get() == nullptr) {
+        if (bytes.get() == nullptr) {
             return -1;
         }
-
+        const uint32_t read_size = std::min(static_cast<uint32_t>(bytes.size()), size);
         memcpy(buf, bytes.get(), read_size);
         return read_size;
     }
diff --git a/packages/MtpDocumentsProvider/res/values/strings.xml b/packages/MtpDocumentsProvider/res/values/strings.xml
index 7a4087b..43a420c 100644
--- a/packages/MtpDocumentsProvider/res/values/strings.xml
+++ b/packages/MtpDocumentsProvider/res/values/strings.xml
@@ -16,9 +16,13 @@
 
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Title of the external storage application [CHAR LIMIT=32] -->
-    <string name="app_label">MTP Storage</string>
+    <string name="app_label">Files</string>
     <!-- Name of MTP root shown in UI. Please align the two strings (device
          model and storage name) in proper order in the language.
          [CHAR LIMIT=32] -->
     <string name="root_name"><xliff:g id="device_model" example="Nexus 9">%1$s</xliff:g> <xliff:g id="storage_name" example="Internal Storage">%2$s</xliff:g></string>
+    <!-- Title of notification showing Files app is accessing files in a MTP device. [CHAR LIMIT=60]-->
+    <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>
 </resources>
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
index 02d07b9..fa99a38 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
@@ -16,19 +16,23 @@
 
 package com.android.mtp;
 
+import android.annotation.Nullable;
+
 class MtpDeviceRecord {
     public final int deviceId;
     public final String name;
     public final boolean opened;
     public final MtpRoot[] roots;
-    public final int[] operationsSupported;
+    public final @Nullable int[] operationsSupported;
+    public final @Nullable int[] eventsSupported;
 
-    MtpDeviceRecord(
-            int deviceId, String name, boolean opened, MtpRoot[] roots, int[] operationsSupported) {
+    MtpDeviceRecord(int deviceId, String name, boolean opened, MtpRoot[] roots,
+                    @Nullable int[] operationsSupported, @Nullable int[] eventsSupported) {
         this.deviceId = deviceId;
         this.name = name;
         this.opened = opened;
         this.roots = roots;
         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 3381656..3ac1b3d 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -37,10 +37,10 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -103,18 +103,28 @@
     }
 
     @VisibleForTesting
-    void onCreateForTesting(
+    boolean onCreateForTesting(
             Resources resources,
             MtpManager mtpManager,
             ContentResolver resolver,
-            MtpDatabase database) {
+            MtpDatabase database,
+            StorageManager storageManager) {
         mResources = resources;
         mMtpManager = mtpManager;
         mResolver = resolver;
         mDeviceToolkits = new HashMap<Integer, DeviceToolkit>();
         mDatabase = database;
         mRootScanner = new RootScanner(mResolver, mResources, mMtpManager, mDatabase);
+        mAppFuse = new AppFuse(TAG, new AppFuseCallback());
+        // TODO: Mount AppFuse on demands.
+        try {
+            mAppFuse.mount(storageManager);
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to start app fuse.", e);
+            return false;
+        }
         resume();
+        return true;
     }
 
     @Override
@@ -165,7 +175,7 @@
                     // Fallback to non-seekable file descriptor.
                     // TODO: Use getPartialObject64 for MTP devices that support Android vendor
                     // extension.
-                    if (fileSize <= 0xffffffff) {
+                    if (fileSize <= 0xffffffffl) {
                         return mAppFuse.openFile(Integer.parseInt(documentId));
                     } else {
                         return getPipeManager(identifier).readDocument(mMtpManager, identifier);
@@ -305,6 +315,7 @@
                 throw new RuntimeException(e);
             } finally {
                 mDatabase.close();
+                mAppFuse.close();
                 super.shutdown();
             }
         }
@@ -385,9 +396,11 @@
         @Override
         public byte[] getObjectBytes(int inode, long offset, int size) throws IOException {
             final Identifier identifier = mDatabase.createIdentifier(Integer.toString(inode));
-            mMtpManager.getPartialObject(
-                    identifier.mDeviceId, identifier.mObjectHandle, (int) offset, size, mBytes);
-            return mBytes;
+            final long readSize = mMtpManager.getPartialObject(
+                    identifier.mDeviceId, identifier.mObjectHandle, offset, size, mBytes);
+            // TODO: Change signature so that getObjectBytes can return read size without copying
+            // bytes.
+            return Arrays.copyOf(mBytes, (int) readSize);
         }
 
         @Override
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
index b0cff83..5bede86 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
@@ -37,7 +37,6 @@
     static final String ACTION_OPEN_DEVICE = "com.android.mtp.OPEN_DEVICE";
     static final String ACTION_CLOSE_DEVICE = "com.android.mtp.CLOSE_DEVICE";
     static final String EXTRA_DEVICE = "device";
-    private static final int FOREGROUND_NOTIFICATION_ID = 1;
 
     NotificationManager mNotificationManager;
 
@@ -67,6 +66,7 @@
                         break;
 
                     case ACTION_CLOSE_DEVICE:
+                        mNotificationManager.cancel(device.getDeviceId());
                         provider.closeDevice(device.getDeviceId());
                         break;
 
@@ -90,36 +90,40 @@
     private boolean updateForegroundState() {
         final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
         final int[] deviceIds = provider.getOpenedDeviceIds();
-        String message = null;
-        if (deviceIds.length != 0) {
-            // TODO: Localize the message.
-            // TODO: Add buttons "Open in Files" and "Open in Apps" if needed.
-            if (deviceIds.length > 1) {
-                message = deviceIds.length + " devices are being connected.";
-            } else {
+        int notificationId = 0;
+        Notification notification = null;
+        for (final int deviceId : deviceIds) {
+            try {
+                final String title = getResources().getString(
+                        R.string.accessing_notification_title,
+                        provider.getDeviceName(deviceIds[0]));
+                final String description = getResources().getString(
+                        R.string.accessing_notification_description);
+                notificationId = deviceId;
+                notification = new Notification.Builder(this)
+                        .setLocalOnly(true)
+                        .setContentTitle(title)
+                        .setContentText(description)
+                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
+                        .setCategory(Notification.CATEGORY_SYSTEM)
+                        .setPriority(Notification.PRIORITY_LOW)
+                        .build();
+                mNotificationManager.notify(deviceId, notification);
+            } catch (IOException exp) {
+                logErrorMessage(exp);
+                // If we failed to obtain device name, it looks the device is unusable.
+                // Because this is the last device we opened, we should hide the notification
+                // for the case.
                 try {
-                    message = provider.getDeviceName(deviceIds[0]) + " is being connected.";
-                } catch (IOException exp) {
-                    logErrorMessage(exp);
-                    // If we failed to obtain device name, it looks the device is unusable.
-                    // Because this is the last device we opened, we should hide the notification
-                    // for the case.
-                    try {
-                        provider.closeDevice(deviceIds[0]);
-                    } catch (IOException | InterruptedException closeError) {
-                        logErrorMessage(closeError);
-                    }
+                    provider.closeDevice(deviceIds[0]);
+                } catch (IOException | InterruptedException closeError) {
+                    logErrorMessage(closeError);
                 }
             }
         }
-        if (message != null) {
-            final Notification notification = new Notification.Builder(this)
-                    .setContentTitle(message)
-                    .setSmallIcon(android.R.drawable.ic_menu_camera)
-                    .setCategory(Notification.CATEGORY_SYSTEM)
-                    .setPriority(Notification.PRIORITY_LOW)
-                    .build();
-            startForeground(FOREGROUND_NOTIFICATION_ID, notification);
+
+        if (notification != null) {
+            startForeground(notificationId, notification);
             return true;
         } else {
             stopForeground(true /* removeNotification */);
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 0d81a30..efe5ff1 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -129,6 +129,7 @@
             final String name = device.getProductName();
             MtpRoot[] roots;
             int[] operationsSupported = null;
+            int[] eventsSupported = null;
             if (opened) {
                 try {
                     roots = getRoots(device.getDeviceId());
@@ -142,16 +143,14 @@
                 final MtpDeviceInfo info = mtpDevice.getDeviceInfo();
                 if (info != null) {
                     operationsSupported = mtpDevice.getDeviceInfo().getOperationsSupported();
-                }
-                if (operationsSupported == null) {
-                    operationsSupported = new int[0];
+                    eventsSupported = mtpDevice.getDeviceInfo().getEventsSupported();
                 }
             } else {
                 roots = new MtpRoot[0];
-                operationsSupported = new int[0];
             }
             devices.add(new MtpDeviceRecord(
-                    device.getDeviceId(), name, opened, roots, operationsSupported));
+                    device.getDeviceId(), name, opened, roots, operationsSupported,
+                    eventsSupported));
         }
         return devices.toArray(new MtpDeviceRecord[devices.size()]);
     }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
index c39d5b3..97ea717 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
@@ -77,7 +77,7 @@
     public void testPutSingleStorageDocuments() throws Exception {
         mDatabase.getMapper().startAddingDocuments(null);
         mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], new int[0]));
+                new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null));
         mDatabase.getMapper().stopAddingDocuments(null);
 
         mDatabase.getMapper().startAddingDocuments("1");
@@ -425,9 +425,9 @@
         };
         mDatabase.getMapper().startAddingDocuments(null);
         mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device A", true, new MtpRoot[0], new int[0]));
+                new MtpDeviceRecord(0, "Device A", true, new MtpRoot[0], null, null));
         mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(1, "Device B", true, new MtpRoot[0], new int[0]));
+                new MtpDeviceRecord(1, "Device B", true, new MtpRoot[0], null, null));
         mDatabase.getMapper().stopAddingDocuments(null);
 
         mDatabase.getMapper().startAddingDocuments("1");
@@ -562,7 +562,7 @@
 
         mDatabase.getMapper().startAddingDocuments(null);
         mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device",  false,  new MtpRoot[0], new int[0]));
+                new MtpDeviceRecord(0, "Device",  false,  new MtpRoot[0], null, null));
         mDatabase.getMapper().stopAddingDocuments(null);
 
         mDatabase.getMapper().startAddingDocuments("1");
@@ -640,7 +640,7 @@
     public void testReplaceExistingRoots() {
         mDatabase.getMapper().startAddingDocuments(null);
         mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], new int[0]));
+                new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null));
         mDatabase.getMapper().stopAddingDocuments(null);
 
         // The client code should be able to replace existing rows with new information.
@@ -691,7 +691,7 @@
         // Add one.
         mDatabase.getMapper().startAddingDocuments(null);
         mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], new int[0]));
+                new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null));
         mDatabase.getMapper().stopAddingDocuments(null);
 
         mDatabase.getMapper().startAddingDocuments("1");
@@ -745,7 +745,7 @@
         // Add device document.
         mDatabase.getMapper().startAddingDocuments(null);
         mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device", false, new MtpRoot[0], new int[0]));
+                new MtpDeviceRecord(0, "Device", false, new MtpRoot[0], null, null));
         mDatabase.getMapper().stopAddingDocuments(null);
 
         // It the device does not have storages, it shows a device root.
@@ -895,7 +895,7 @@
     public void testGetDocumentIdForDevice() {
         mDatabase.getMapper().startAddingDocuments(null);
         mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(100, "Device", true, new MtpRoot[0], new int[0]));
+                new MtpDeviceRecord(100, "Device", true, new MtpRoot[0], null, null));
         mDatabase.getMapper().stopAddingDocuments(null);
         assertEquals("1", mDatabase.getDocumentIdForDevice(100));
     }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index 44841af..7066f7d 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -20,18 +20,25 @@
 import android.mtp.MtpConstants;
 import android.mtp.MtpObjectInfo;
 import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.os.storage.StorageManager;
 import android.provider.DocumentsContract.Root;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
 import android.provider.DocumentsContract;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.concurrent.TimeoutException;
 
 import static com.android.mtp.MtpDatabase.strings;
 
-@SmallTest
+@MediumTest
 public class MtpDocumentsProviderTest extends AndroidTestCase {
     private final static Uri ROOTS_URI =
             DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);
@@ -69,7 +76,8 @@
                             2048 /* total space */,
                             "" /* no volume identifier */)
                 },
-                new int[0]));
+                null,
+                null));
 
         mProvider.openDevice(0);
         mResolver.waitForNotification(ROOTS_URI, 1);
@@ -109,7 +117,8 @@
                             2048 /* total space */,
                             "" /* no volume identifier */)
                 },
-                new int[0]));
+                null,
+                null));
         mProvider.openDevice(0);
         mResolver.waitForNotification(ROOTS_URI, 1);
     }
@@ -130,7 +139,8 @@
                                 2048 /* total space */,
                                 "" /* no volume identifier */)
                 },
-                new int[0]));
+                null,
+                null));
         mMtpManager.addValidDevice(new MtpDeviceRecord(
                 1,
                 "Device",
@@ -145,7 +155,8 @@
                             4096 /* total space */,
                             "Identifier B" /* no volume identifier */)
                 },
-                new int[0]));
+                null,
+                null));
 
         {
             mProvider.openDevice(0);
@@ -180,7 +191,7 @@
     public void testQueryRoots_error() throws Exception {
         setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(new MtpDeviceRecord(
-                0, "Device A", false /* unopened */, new MtpRoot[0], new int[0]));
+                0, "Device A", false /* unopened */, new MtpRoot[0], null, null));
         mMtpManager.addValidDevice(new MtpDeviceRecord(
                 1,
                 "Device",
@@ -195,7 +206,8 @@
                             4096 /* total space */,
                             "Identifier B" /* no volume identifier */)
                 },
-                new int[0]));
+                null,
+                null));
         {
             mProvider.openDevice(0);
             mProvider.openDevice(1);
@@ -416,10 +428,71 @@
                         MtpDocumentsProvider.AUTHORITY, "1")));
     }
 
+    public void testOpenDocument() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        setupRoots(0, new MtpRoot[] {
+                new MtpRoot(0, 0, "Device", "Storage", 0, 0, "")
+        });
+        final byte[] bytes = "Hello world".getBytes();
+        setupDocuments(0, 0, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN, "1", new MtpObjectInfo[] {
+                new MtpObjectInfo.Builder()
+                        .setName("test.txt")
+                        .setObjectHandle(1)
+                        .setCompressedSize(bytes.length)
+                        .setParent(-1)
+                        .build()
+        });
+        mMtpManager.setImportFileBytes(0, 1, bytes);
+        try (final ParcelFileDescriptor fd = mProvider.openDocument("3", "r", null)) {
+            final byte[] readBytes = new byte[5];
+            assertEquals(6, Os.lseek(fd.getFileDescriptor(), 6, OsConstants.SEEK_SET));
+            assertEquals(5, Os.read(fd.getFileDescriptor(), readBytes, 0, 5));
+            assertTrue(Arrays.equals("world".getBytes(), readBytes));
+
+            assertEquals(0, Os.lseek(fd.getFileDescriptor(), 0, OsConstants.SEEK_SET));
+            assertEquals(5, Os.read(fd.getFileDescriptor(), readBytes, 0, 5));
+            assertTrue(Arrays.equals("Hello".getBytes(), readBytes));
+        }
+    }
+
+    public void testOpenDocument_shortBytes() throws Exception {
+        mMtpManager = new TestMtpManager(getContext()) {
+            @Override
+            MtpObjectInfo getObjectInfo(int deviceId, int objectHandle) throws IOException {
+                if (objectHandle == 1) {
+                    return new MtpObjectInfo.Builder(super.getObjectInfo(deviceId, objectHandle))
+                            .setObjectHandle(1).setCompressedSize(1024 * 1024).build();
+                }
+
+                return super.getObjectInfo(deviceId, objectHandle);
+            }
+        };
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        setupRoots(0, new MtpRoot[] {
+                new MtpRoot(0, 0, "Device", "Storage", 0, 0, "")
+        });
+        final byte[] bytes = "Hello world".getBytes();
+        setupDocuments(0, 0, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN, "1", new MtpObjectInfo[] {
+                new MtpObjectInfo.Builder()
+                        .setName("test.txt")
+                        .setObjectHandle(1)
+                        .setCompressedSize(bytes.length)
+                        .setParent(-1)
+                        .build()
+        });
+        mMtpManager.setImportFileBytes(0, 1, bytes);
+        try (final ParcelFileDescriptor fd = mProvider.openDocument("3", "r", null)) {
+            final byte[] readBytes = new byte[1024 * 1024];
+            assertEquals(11, Os.read(fd.getFileDescriptor(), readBytes, 0, readBytes.length));
+        }
+    }
+
     private void setupProvider(int flag) {
         mDatabase = new MtpDatabase(getContext(), flag);
         mProvider = new MtpDocumentsProvider();
-        mProvider.onCreateForTesting(mResources, mMtpManager, mResolver, mDatabase);
+        final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
+        assertTrue(mProvider.onCreateForTesting(
+                mResources, mMtpManager, mResolver, mDatabase, storageManager));
     }
 
     private String[] getStrings(Cursor cursor) {
@@ -438,7 +511,7 @@
             throws InterruptedException, TimeoutException, IOException {
         final int changeCount = mResolver.getChangeCount(ROOTS_URI);
         mMtpManager.addValidDevice(
-                new MtpDeviceRecord(deviceId, "Device", false /* unopened */, roots, new int[0]));
+                new MtpDeviceRecord(deviceId, "Device", 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 914a4af..9ebe4d1 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
@@ -87,6 +87,13 @@
         getInstrumentation().show(Arrays.toString(records[0].operationsSupported));
     }
 
+    public void testEventsSupported() {
+        final MtpDeviceRecord[] records = mManager.getDevices();
+        assertEquals(1, records.length);
+        assertNotNull(records[0].eventsSupported);
+        getInstrumentation().show(Arrays.toString(records[0].eventsSupported));
+    }
+
     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 3934b88..1aaeb60 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
@@ -76,7 +76,7 @@
                 result[i] = device;
             } else {
                 result[i] = new MtpDeviceRecord(
-                        device.deviceId, device.name, device.opened, new MtpRoot[0], new int[0]);
+                        device.deviceId, device.name, device.opened, new MtpRoot[0], null, null);
             }
         }
         return result;
@@ -90,7 +90,7 @@
         }
         mDevices.put(
                 deviceId,
-                new MtpDeviceRecord(device.deviceId, device.name, true, device.roots, new int[0]));
+                new MtpDeviceRecord(device.deviceId, device.name, true, device.roots, null, null));
     }
 
     @Override
@@ -101,7 +101,7 @@
         }
         mDevices.put(
                 deviceId,
-                new MtpDeviceRecord(device.deviceId, device.name, false, device.roots, new int[0]));
+                new MtpDeviceRecord(device.deviceId, device.name, false, device.roots, null, null));
     }
 
     @Override
@@ -208,4 +208,16 @@
     byte[] getObject(int deviceId, int objectHandle, int expectedSize) throws IOException {
         return mImportFileBytes.get(pack(deviceId, objectHandle));
     }
+
+    @Override
+    long getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer)
+            throws IOException {
+        final byte[] bytes = mImportFileBytes.get(pack(deviceId, objectHandle));
+        int i = 0;
+        while (i < size && i + offset < bytes.length) {
+            buffer[i] = bytes[(int) (i + offset)];
+            i++;
+        }
+        return i;
+    }
 }
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
index 19c695b..19cbee7 100644
--- a/packages/PrintSpooler/res/values-es-rUS/strings.xml
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -92,7 +92,7 @@
   </string-array>
     <string name="print_write_error_message" msgid="5787642615179572543">"No se pudo escribir en el archivo."</string>
     <string name="print_error_default_message" msgid="8602678405502922346">"No funcionó. Vuelve a intentarlo."</string>
-    <string name="print_error_retry" msgid="1426421728784259538">"Reintentar"</string>
+    <string name="print_error_retry" msgid="1426421728784259538">"Volver a intentar"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impresora no está disponible en este momento."</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparando vista previa…"</string>
 </resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
index cd30e26..46a2098 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.printspooler.ui;
 
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Loader;
@@ -452,7 +453,7 @@
         return mPersistenceManager.mReadHistoryCompleted;
     }
 
-    public void setTrackedPrinter(PrinterId printerId) {
+    public void setTrackedPrinter(@Nullable PrinterId printerId) {
         if (isStarted() && mDiscoverySession != null
                 && mDiscoverySession.isPrinterDiscoveryStarted()) {
             if (mTrackedPrinter != null) {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 811adda..743df99 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -1003,7 +1003,9 @@
         if (currMediaSize == null) {
             attributes.setMediaSize(defaults.getMediaSize());
         } else {
-            boolean foundCurrentMediaSize = false;
+            MediaSize newMediaSize = null;
+            boolean isPortrait = currMediaSize.isPortrait();
+
             // Try to find the current media size in the capabilities as
             // it may be in a different orientation.
             MediaSize currMediaSizePortrait = currMediaSize.asPortrait();
@@ -1011,14 +1013,21 @@
             for (int i = 0; i < mediaSizeCount; i++) {
                 MediaSize mediaSize = sortedMediaSizes.get(i);
                 if (currMediaSizePortrait.equals(mediaSize.asPortrait())) {
-                    attributes.setMediaSize(currMediaSize);
-                    foundCurrentMediaSize = true;
+                    newMediaSize = mediaSize;
                     break;
                 }
             }
             // If we did not find the current media size fall back to default.
-            if (!foundCurrentMediaSize) {
-                attributes.setMediaSize(defaults.getMediaSize());
+            if (newMediaSize == null) {
+                newMediaSize = defaults.getMediaSize();
+            }
+
+            if (newMediaSize != null) {
+                if (isPortrait) {
+                    attributes.setMediaSize(newMediaSize.asPortrait());
+                } else {
+                    attributes.setMediaSize(newMediaSize.asLandscape());
+                }
             }
         }
 
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
index cbc568a..6d60bb8 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
@@ -16,6 +16,7 @@
 
 package com.android.printspooler.ui;
 
+import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.LoaderManager.LoaderCallbacks;
 import android.content.Loader;
@@ -89,7 +90,7 @@
         return false;
     }
 
-    public void setTrackedPrinter(PrinterId printerId) {
+    public void setTrackedPrinter(@Nullable PrinterId printerId) {
         FusedPrintersProvider provider = getPrinterProvider();
         if (provider != null) {
             provider.setTrackedPrinter(printerId);
diff --git a/packages/SettingsLib/res/values/attrs.xml b/packages/SettingsLib/res/values/attrs.xml
index 46267a2..3e1fc4a 100644
--- a/packages/SettingsLib/res/values/attrs.xml
+++ b/packages/SettingsLib/res/values/attrs.xml
@@ -16,6 +16,12 @@
 
 <resources>
     <declare-styleable name="RestrictedPreference">
-        <attr name="userRestriction" format="string"/>
+        <attr name="userRestriction" format="string" />
+        <attr name="useAdminDisabledSummary" format="boolean" />
     </declare-styleable>
-</resources>
\ No newline at end of file
+    <declare-styleable name="WifiEncryptionState">
+        <attr name="state_encrypted" format="boolean" />
+    </declare-styleable>
+    <attr name="wifi_signal" format="reference" />
+
+</resources>
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 9a1d6a4..811751c 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -35,4 +35,7 @@
     <!-- Lock icon for preferences locked by admin -->
     <dimen name="restricted_lock_icon_size">16dp</dimen>
     <dimen name="restricted_lock_icon_padding">4dp</dimen>
+
+    <dimen name="wifi_preference_badge_padding">8dip</dimen>
+
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 6dfa9ad..d3c8416 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -765,4 +765,7 @@
     <!-- Battery Info screen. Value for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="battery_info_status_full">Full</string>
 
+    <!-- Summary for settings preference disabled by administrator [CHAR LIMIT=50] -->
+    <string name="disabled_by_admin_summary_text">Disabled by administrator</string>
+
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index d69250b..d3c1364 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
+import android.content.pm.UserInfo;
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
@@ -36,6 +37,8 @@
 import android.view.MenuItem;
 import android.widget.TextView;
 
+import com.android.internal.widget.LockPatternUtils;
+
 import java.util.List;
 
 /**
@@ -60,15 +63,18 @@
      *
      * @param userRestriction Restriction to check
      * @param userId User which we need to check if restriction is enforced on.
-     * @return EnforcedAdmin Object containing the enforce admin and admin user details, or
-     * {@code null} If the restriction is not set. If the restriction is set by both device owner
-     * and profile owner, then the admin will be set to {@code null} and userId to
+     * @return EnforcedAdmin Object containing the enforced admin component and admin user details,
+     * or {@code null} If the restriction is not set. If the restriction is set by both device owner
+     * and profile owner, then the admin component will be set to {@code null} and userId to
      * {@link UserHandle#USER_NULL}.
      */
     public static EnforcedAdmin checkIfRestrictionEnforced(Context context,
             String userRestriction, int userId) {
         DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
+        if (dpm == null) {
+            return null;
+        }
         ComponentName deviceOwner = dpm.getDeviceOwnerComponentOnAnyUser();
         int deviceOwnerUserId = dpm.getDeviceOwnerUserId();
         boolean enforcedByDeviceOwner = false;
@@ -109,45 +115,80 @@
     }
 
     /**
-     * Checks if lock screen notification features are disabled by policy. This should be
-     * only used for keyguard notification features but not the keyguard features
-     * (e.g. KEYGUARD_DISABLE_FINGERPRINT) where a profile owner can set them on the parent user
-     * as it won't work for that case.
+     * Checks if keyguard features are disabled by policy.
      *
-     * @param keyguardNotificationFeatures Could be any of notification features that can be
+     * @param keyguardFeatures Could be any of keyguard features that can be
      * disabled by {@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures}.
-     * @return EnforcedAdmin Object containing the enforce admin and admin user details, or
-     * {@code null} If the notification features are not disabled. If the restriction is set by
-     * multiple admins, then the admin will be set to {@code null} and userId to
+     * @return EnforcedAdmin Object containing the enforced admin component and admin user details,
+     * or {@code null} If the notification features are not disabled. If the restriction is set by
+     * multiple admins, then the admin component will be set to {@code null} and userId to
      * {@link UserHandle#USER_NULL}.
      */
-    public static EnforcedAdmin checkIfKeyguardNotificationFeaturesDisabled(Context context,
-            int keyguardNotificationFeatures) {
+    public static EnforcedAdmin checkIfKeyguardFeaturesDisabled(Context context,
+            int keyguardFeatures) {
         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
-        boolean isDisabledByMultipleAdmins = false;
-        ComponentName adminComponent = null;
-        List<ComponentName> admins = dpm.getActiveAdmins();
-        if (admins != null) {
-            int disabledKeyguardFeatures;
+        if (dpm == null) {
+            return null;
+        }
+        final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
+        EnforcedAdmin enforcedAdmin = null;
+        final int userId = UserHandle.myUserId();
+        if (um.getUserInfo(userId).isManagedProfile()) {
+            final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userId);
+            if (admins == null) {
+                return null;
+            }
             for (ComponentName admin : admins) {
-                disabledKeyguardFeatures = dpm.getKeyguardDisabledFeatures(admin);
-                if ((disabledKeyguardFeatures & keyguardNotificationFeatures) != 0) {
-                    if (adminComponent == null) {
-                        adminComponent = admin;
+                if ((dpm.getKeyguardDisabledFeatures(admin, userId) & keyguardFeatures) != 0) {
+                    if (enforcedAdmin == null) {
+                        enforcedAdmin = new EnforcedAdmin(admin, userId);
                     } else {
-                        isDisabledByMultipleAdmins = true;
-                        break;
+                        return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
                     }
                 }
             }
-        }
-        EnforcedAdmin enforcedAdmin = null;
-        if (adminComponent != null) {
-            if (!isDisabledByMultipleAdmins) {
-                enforcedAdmin = new EnforcedAdmin(adminComponent, UserHandle.myUserId());
-            } else {
-                enforcedAdmin = new EnforcedAdmin();
+        } else {
+            // Consider all admins for this user and the profiles that are visible from this
+            // user that do not use a separate work challenge.
+            for (UserInfo userInfo : um.getProfiles(userId)) {
+                final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id);
+                if (admins == null) {
+                    return null;
+                }
+                final boolean isSeparateProfileChallengeEnabled =
+                        lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id);
+                for (ComponentName admin : admins) {
+                    if (!isSeparateProfileChallengeEnabled) {
+                        if ((dpm.getKeyguardDisabledFeatures(admin, userInfo.id)
+                                    & keyguardFeatures) != 0) {
+                            if (enforcedAdmin == null) {
+                                enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
+                            } else {
+                                return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                            }
+                            // This same admins could have set policies both on the managed profile
+                            // and on the parent. So, if the admin has set the policy on the
+                            // managed profile here, we don't need to further check if that admin
+                            // has set policy on the parent admin.
+                            continue;
+                        }
+                    }
+                    if (userInfo.isManagedProfile()) {
+                        // If userInfo.id is a managed profile, we also need to look at
+                        // the policies set on the parent.
+                        DevicePolicyManager parentDpm = dpm.getParentProfileInstance(admin);
+                        if ((parentDpm.getKeyguardDisabledFeatures(admin, userInfo.id)
+                                & keyguardFeatures) != 0) {
+                            if (enforcedAdmin == null) {
+                                enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
+                            } else {
+                                return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                            }
+                        }
+                    }
+                }
             }
         }
         return enforcedAdmin;
@@ -170,6 +211,9 @@
             if (ipm.getBlockUninstallForUser(packageName, userId)) {
                 DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                         Context.DEVICE_POLICY_SERVICE);
+                if (dpm == null) {
+                    return null;
+                }
                 ComponentName admin = dpm.getProfileOwner();
                 if (admin == null) {
                     admin = dpm.getDeviceOwnerComponentOnCallingUser();
@@ -197,6 +241,9 @@
         }
         DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
+        if (dpm == null) {
+            return null;
+        }
         boolean isAccountTypeDisabled = false;
         String[] disabledTypes = dpm.getAccountTypesWithManagementDisabled();
         for (String type : disabledTypes) {
@@ -221,7 +268,7 @@
     public static EnforcedAdmin checkIfAutoTimeRequired(Context context) {
         DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
-        if (dpm.getAutoTimeRequired()) {
+        if (dpm == null || !dpm.getAutoTimeRequired()) {
             return null;
         }
         ComponentName adminComponent = dpm.getDeviceOwnerComponentOnCallingUser();
@@ -240,6 +287,9 @@
     public static EnforcedAdmin checkIfPasswordQualityIsSet(Context context) {
         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
+        if (dpm == null) {
+            return null;
+        }
         boolean isDisabledByMultipleAdmins = false;
         ComponentName adminComponent = null;
         List<ComponentName> admins = dpm.getActiveAdmins();
@@ -268,9 +318,84 @@
         return enforcedAdmin;
     }
 
+    /**
+     * Checks if any admin has set maximum time to lock.
+     *
+     * @return EnforcedAdmin Object containing the enforced admin component and admin user details,
+     * or {@code null} if no admin has set this restriction. If multiple admins has set this, then
+     * the admin component will be set to {@code null} and userId to {@link UserHandle#USER_NULL}
+     */
+    public static EnforcedAdmin checkIfMaximumTimeToLockIsSet(Context context) {
+        final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
+        EnforcedAdmin enforcedAdmin = null;
+        final int userId = UserHandle.myUserId();
+        if (lockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+            // If the user has a separate challenge, only consider the admins in that user.
+            final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userId);
+            if (admins == null) {
+                return null;
+            }
+            for (ComponentName admin : admins) {
+                if (dpm.getMaximumTimeToLock(admin, userId) > 0) {
+                    if (enforcedAdmin == null) {
+                        enforcedAdmin = new EnforcedAdmin(admin, userId);
+                    } else {
+                        return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                    }
+                }
+            }
+        } else {
+            // Return all admins for this user and the profiles that are visible from this
+            // user that do not use a separate work challenge.
+            final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+            for (UserInfo userInfo : um.getProfiles(userId)) {
+                final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id);
+                if (admins == null) {
+                    return null;
+                }
+                final boolean isSeparateProfileChallengeEnabled =
+                        lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id);
+                for (ComponentName admin : admins) {
+                    if (!isSeparateProfileChallengeEnabled) {
+                        if (dpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
+                            if (enforcedAdmin == null) {
+                                enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
+                            } else {
+                                return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                            }
+                            // This same admins could have set policies both on the managed profile
+                            // and on the parent. So, if the admin has set the policy on the
+                            // managed profile here, we don't need to further check if that admin
+                            // has set policy on the parent admin.
+                            continue;
+                        }
+                    }
+                    if (userInfo.isManagedProfile()) {
+                        // If userInfo.id is a managed profile, we also need to look at
+                        // the policies set on the parent.
+                        DevicePolicyManager parentDpm = dpm.getParentProfileInstance(admin);
+                        if (parentDpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
+                            if (enforcedAdmin == null) {
+                                enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
+                            } else {
+                                return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return enforcedAdmin;
+    }
+
     public static EnforcedAdmin getProfileOrDeviceOwnerOnCallingUser(Context context) {
         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
+        if (dpm == null) {
+            return null;
+        }
         ComponentName adminComponent = dpm.getDeviceOwnerComponentOnCallingUser();
         if (adminComponent != null) {
             return new EnforcedAdmin(adminComponent, UserHandle.myUserId());
@@ -391,6 +516,9 @@
         public ComponentName component = null;
         public int userId = UserHandle.USER_NULL;
 
+        // We use this to represent the case where a policy is enforced by multiple admins.
+        public final static EnforcedAdmin MULTIPLE_ENFORCED_ADMIN = new EnforcedAdmin();
+
         public EnforcedAdmin(ComponentName component, int userId) {
             this.component = component;
             this.userId = userId;
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
index 13a46d0..810f6eb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreference.java
@@ -65,6 +65,10 @@
         }
     }
 
+    public void useAdminDisabledSummary(boolean useSummary) {
+        mHelper.useAdminDisabledSummary(useSummary);
+    }
+
     @Override
     protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
         mHelper.onAttachedToHierarchy();
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 06aba96..9bd4eb1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -27,6 +27,7 @@
 import android.text.style.ImageSpan;
 import android.util.AttributeSet;
 import android.util.TypedValue;
+import android.view.View;
 import android.widget.TextView;
 
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -44,6 +45,7 @@
     private boolean mDisabledByAdmin;
     private EnforcedAdmin mEnforcedAdmin;
     private String mAttrUserRestriction = null;
+    private boolean mUseAdminDisabledSummary = false;
 
     public RestrictedPreferenceHelper(Context context, Preference preference,
             AttributeSet attrs) {
@@ -68,6 +70,14 @@
                 }
             }
             mAttrUserRestriction = data == null ? null : data.toString();
+
+            final TypedValue useAdminDisabledSummary =
+                    attributes.peekValue(R.styleable.RestrictedPreference_useAdminDisabledSummary);
+            if (useAdminDisabledSummary != null) {
+                mUseAdminDisabledSummary =
+                        (useAdminDisabledSummary.type == TypedValue.TYPE_INT_BOOLEAN
+                                && useAdminDisabledSummary.data != 0);
+            }
         }
     }
 
@@ -82,6 +92,21 @@
                 holder.itemView.setEnabled(true);
             }
         }
+        if (mUseAdminDisabledSummary) {
+            final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
+            if (summaryView != null) {
+                if (mDisabledByAdmin) {
+                    summaryView.setText(R.string.disabled_by_admin_summary_text);
+                    summaryView.setVisibility(View.VISIBLE);
+                } else {
+                    summaryView.setVisibility(View.GONE);
+                }
+            }
+        }
+    }
+
+    public void useAdminDisabledSummary(boolean useSummary) {
+        mUseAdminDisabledSummary = useSummary;
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index 84e2bff..6cae8aa 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -65,6 +65,10 @@
         }
     }
 
+    public void useAdminDisabledSummary(boolean useSummary) {
+        mHelper.useAdminDisabledSummary(useSummary);
+    }
+
     @Override
     protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
         mHelper.onAttachedToHierarchy();
diff --git a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
index 58a477e..1859207 100644
--- a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
@@ -17,6 +17,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -38,14 +39,39 @@
 
     private static final String TAG = "SuggestionParser";
 
+    // If defined, only returns this suggestion if the feature is supported.
+    public static final String META_DATA_REQUIRE_FEATURE = "com.android.settings.require_feature";
+
+    /**
+     * Allows suggestions to appear after a certain number of days, and to re-appear if dismissed.
+     * For instance:
+     * 0,10
+     * Will appear immediately, but if the user removes it, it will come back after 10 days.
+     *
+     * Another example:
+     * 10,30
+     * Will only show up after 10 days, and then again after 30.
+     */
+    public static final String META_DATA_DISMISS_CONTROL = "com.android.settings.dismiss";
+
+    // Shared prefs keys for storing dismissed state.
+    // Index into current dismissed state.
+    private static final String DISMISS_INDEX = "_dismiss_index";
+    private static final String SETUP_TIME = "_setup_time";
+    private static final String IS_DISMISSED = "_is_dismissed";
+
+    private static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
+
     private final Context mContext;
     private final List<SuggestionCategory> mSuggestionList;
     private final ArrayMap<Pair<String, String>, Tile> addCache = new ArrayMap<>();
+    private final SharedPreferences mSharedPrefs;
 
-    public SuggestionParser(Context context, int orderXml) {
+    public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
         mContext = context;
         mSuggestionList = (List<SuggestionCategory>) new SuggestionOrderInflater(mContext)
                 .parse(orderXml);
+        mSharedPrefs = sharedPrefs;
     }
 
     public List<Tile> getSuggestions() {
@@ -57,6 +83,23 @@
         return suggestions;
     }
 
+    /**
+     * Dismisses a suggestion, returns true if the suggestion has no more dismisses left and should
+     * be disabled.
+     */
+    public boolean dismissSuggestion(Tile suggestion) {
+        String keyBase = suggestion.intent.getComponent().flattenToShortString();
+        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
+        String dismissControl = suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
+        if (dismissControl == null || parseDismissString(dismissControl).length == index) {
+            return true;
+        }
+        mSharedPrefs.edit()
+                .putBoolean(keyBase + IS_DISMISSED, true)
+                .commit();
+        return false;
+    }
+
     private void readSuggestions(SuggestionCategory category, List<Tile> suggestions) {
         int countBefore = suggestions.size();
         Intent intent = new Intent(Intent.ACTION_MAIN);
@@ -66,6 +109,11 @@
         }
         TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
                 addCache, null, suggestions, true, false);
+        for (int i = countBefore; i < suggestions.size(); i++) {
+            if (!isAvailable(suggestions.get(i)) || isDismissed(suggestions.get(i))) {
+                suggestions.remove(i--);
+            }
+        }
         if (!category.multiple && suggestions.size() > (countBefore + 1)) {
             // If there are too many, remove them all and only re-add the one with the highest
             // priority.
@@ -80,6 +128,59 @@
         }
     }
 
+    private boolean isAvailable(Tile suggestion) {
+        String featureRequired = suggestion.metaData.getString(META_DATA_REQUIRE_FEATURE);
+        if (featureRequired != null) {
+            return mContext.getPackageManager().hasSystemFeature(featureRequired);
+        }
+        return true;
+    }
+
+    private boolean isDismissed(Tile suggestion) {
+        Object dismissObj = suggestion.metaData.get(META_DATA_DISMISS_CONTROL);
+        if (dismissObj == null) {
+            return false;
+        }
+        String dismissControl = String.valueOf(dismissObj);
+        String keyBase = suggestion.intent.getComponent().flattenToShortString();
+        if (!mSharedPrefs.contains(keyBase + SETUP_TIME)) {
+            mSharedPrefs.edit()
+                    .putLong(keyBase + SETUP_TIME, System.currentTimeMillis())
+                    .commit();
+        }
+        // Default to dismissed, so that we can have suggestions that only first appear after
+        // some number of days.
+        if (!mSharedPrefs.getBoolean(keyBase + IS_DISMISSED, true)) {
+            return false;
+        }
+        int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
+        int currentDismiss = parseDismissString(dismissControl)[index];
+        long time = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0), currentDismiss);
+        if (System.currentTimeMillis() >= time) {
+            // Dismiss timeout has passed, undismiss it.
+            mSharedPrefs.edit()
+                    .putBoolean(keyBase + IS_DISMISSED, false)
+                    .putInt(keyBase + DISMISS_INDEX, index + 1)
+                    .commit();
+            return false;
+        }
+        return true;
+    }
+
+    private long getEndTime(long startTime, int daysDelay) {
+        long days = daysDelay * MILLIS_IN_DAY;
+        return startTime + days;
+    }
+
+    private int[] parseDismissString(String dismissControl) {
+        String[] dismissStrs = dismissControl.split(",");
+        int[] dismisses = new int[dismissStrs.length];
+        for (int i = 0; i < dismissStrs.length; i++) {
+            dismisses[i] = Integer.parseInt(dismissStrs[i]);
+        }
+        return dismisses;
+    }
+
     private static class SuggestionCategory {
         public String category;
         public String pkg;
diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
index 66233b8..f5a2aae 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
@@ -29,12 +29,6 @@
 
 public class TetherUtil {
 
-    // Types of tethering.
-    public static final int TETHERING_INVALID   = -1;
-    public static final int TETHERING_WIFI      = 0;
-    public static final int TETHERING_USB       = 1;
-    public static final int TETHERING_BLUETOOTH = 2;
-
     // Extras used for communicating with the TetherService.
     public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
     public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
@@ -43,14 +37,6 @@
      * Tells the service to run a provision check now.
      */
     public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
-    /**
-     * Enables wifi tethering if the provision check is successful. Used by
-     * QS to enable tethering.
-     */
-    public static final String EXTRA_ENABLE_WIFI_TETHER = "extraEnableWifiTether";
-
-    public static ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(Resources
-            .getSystem().getString(com.android.internal.R.string.config_wifi_tether_enable));
 
     public static boolean setWifiTethering(boolean enable, Context context) {
         final WifiManager wifiManager =
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java b/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
index 2fd043f..dc6002d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
@@ -61,6 +61,8 @@
     @Override
     public void onClick(DialogInterface dialog, int which) {
         UserHandle user = mSelectedTile.userHandle.get(which);
+        // Show menu on top level items.
+        mSelectedTile.intent.putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true);
         getActivity().startActivityAsUser(mSelectedTile.intent, user);
         ((SettingsDrawerActivity) getActivity()).onProfileTileOpen();
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index 3fc0c22..56c4edb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -48,6 +48,8 @@
     protected static final boolean DEBUG_TIMING = false;
     private static final String TAG = "SettingsDrawerActivity";
 
+    static final String EXTRA_SHOW_MENU = "show_drawer_menu";
+
     private static List<DashboardCategory> sDashboardCategories;
     private static HashMap<Pair<String, String>, Tile> sTileCache;
 
@@ -56,6 +58,7 @@
 
     private SettingsDrawerAdapter mDrawerAdapter;
     private DrawerLayout mDrawerLayout;
+    private boolean mShowingMenu;
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -94,7 +97,7 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        if (mDrawerLayout != null && item.getItemId() == android.R.id.home
+        if (mShowingMenu && mDrawerLayout != null && item.getItemId() == android.R.id.home
                 && mDrawerAdapter.getCount() != 0) {
             openDrawer();
             return true;
@@ -116,6 +119,9 @@
 
             new CategoriesUpdater().execute();
         }
+        if (getIntent() != null && getIntent().getBooleanExtra(EXTRA_SHOW_MENU, false)) {
+            showMenuIcon();
+        }
     }
 
     @Override
@@ -171,13 +177,17 @@
         mDrawerAdapter.updateCategories();
         if (mDrawerAdapter.getCount() != 0) {
             mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
-            getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
-            getActionBar().setDisplayHomeAsUpEnabled(true);
         } else {
             mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
         }
     }
 
+    public void showMenuIcon() {
+        mShowingMenu = true;
+        getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
+        getActionBar().setDisplayHomeAsUpEnabled(true);
+    }
+
     public List<DashboardCategory> getDashboardCategories() {
         if (sDashboardCategories == null) {
             sTileCache = new HashMap<>();
@@ -204,8 +214,12 @@
             ProfileSelectDialog.show(getFragmentManager(), tile);
             return false;
         } else if (numUserHandles == 1) {
+            // Show menu on top level items.
+            tile.intent.putExtra(EXTRA_SHOW_MENU, true);
             startActivityAsUser(tile.intent, tile.userHandle.get(0));
         } else {
+            // Show menu on top level items.
+            tile.intent.putExtra(EXTRA_SHOW_MENU, true);
             startActivity(tile.intent);
         }
         return true;
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 5d8668b..e53dd2f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -228,7 +228,7 @@
     private static String getActiveSubscriberId(Context context) {
         final TelephonyManager tele = TelephonyManager.from(context);
         final String actualSubscriberId = tele.getSubscriberId(
-                SubscriptionManager.getDefaultDataSubId());
+                SubscriptionManager.getDefaultDataSubscriptionId());
         return actualSubscriberId;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
new file mode 100644
index 0000000..284827b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.wifi;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
+import android.net.wifi.WifiConfiguration;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.widget.TextView;
+
+import com.android.settingslib.R;
+
+public class AccessPointPreference extends Preference {
+
+    private static final int[] STATE_SECURED = {
+            R.attr.state_encrypted
+    };
+    private static final int[] STATE_NONE = {};
+
+    private static int[] wifi_signal_attributes = { R.attr.wifi_signal };
+
+    private final StateListDrawable mWifiSld;
+    private final int mBadgePadding;
+    private final UserBadgeCache mBadgeCache;
+
+    private TextView mTitleView;
+    private boolean mForSavedNetworks = false;
+    private AccessPoint mAccessPoint;
+    private Drawable mBadge;
+    private int mLevel;
+    private CharSequence mContentDescription;
+
+    static final int[] WIFI_CONNECTION_STRENGTH = {
+            R.string.accessibility_wifi_one_bar,
+            R.string.accessibility_wifi_two_bars,
+            R.string.accessibility_wifi_three_bars,
+            R.string.accessibility_wifi_signal_full
+    };
+
+    // Used for dummy pref.
+    public AccessPointPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mWifiSld = null;
+        mBadgePadding = 0;
+        mBadgeCache = null;
+    }
+
+    public AccessPointPreference(AccessPoint accessPoint, Context context, UserBadgeCache cache,
+            boolean forSavedNetworks) {
+        super(context);
+        mBadgeCache = cache;
+        mAccessPoint = accessPoint;
+        mForSavedNetworks = forSavedNetworks;
+        mAccessPoint.setTag(this);
+        mLevel = -1;
+
+        mWifiSld = (StateListDrawable) context.getTheme()
+                .obtainStyledAttributes(wifi_signal_attributes).getDrawable(0);
+
+        // Distance from the end of the title at which this AP's user badge should sit.
+        mBadgePadding = context.getResources()
+                .getDimensionPixelSize(R.dimen.wifi_preference_badge_padding);
+        refresh();
+    }
+
+    public AccessPoint getAccessPoint() {
+        return mAccessPoint;
+    }
+
+    @Override
+    public void onBindViewHolder(final PreferenceViewHolder view) {
+        super.onBindViewHolder(view);
+        if (mAccessPoint == null) {
+            // Used for dummy pref.
+            return;
+        }
+        Drawable drawable = getIcon();
+        if (drawable != null) {
+            drawable.setLevel(mLevel);
+        }
+
+        mTitleView = (TextView) view.findViewById(com.android.internal.R.id.title);
+        if (mTitleView != null) {
+            // Attach to the end of the title view
+            mTitleView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, mBadge, null);
+            mTitleView.setCompoundDrawablePadding(mBadgePadding);
+        }
+        view.itemView.setContentDescription(mContentDescription);
+    }
+
+    protected void updateIcon(int level, Context context) {
+        if (level == -1) {
+            setIcon(null);
+        } else {
+            if (getIcon() == null) {
+                // To avoid a drawing race condition, we first set the state (SECURE/NONE) and then
+                // set the icon (drawable) to that state's drawable.
+                // If sld is null then we are indexing and therefore do not have access to
+                // (nor need to display) the drawable.
+                if (mWifiSld != null) {
+                    mWifiSld.setState((mAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE)
+                            ? STATE_SECURED
+                            : STATE_NONE);
+                    Drawable drawable = mWifiSld.getCurrent();
+                    if (!mForSavedNetworks) {
+                        setIcon(drawable);
+                    } else {
+                        setIcon(null);
+                    }
+                }
+            }
+        }
+    }
+
+    protected void updateBadge(Context context) {
+        WifiConfiguration config = mAccessPoint.getConfig();
+        if (config != null) {
+            // Fetch badge (may be null)
+            // Get the badge using a cache since the PM will ask the UserManager for the list
+            // of profiles every time otherwise.
+            mBadge = mBadgeCache.getUserBadge(config.creatorUid);
+        }
+    }
+
+    /**
+     * Updates the title and summary; may indirectly call notifyChanged().
+     */
+    public void refresh() {
+        if (mForSavedNetworks) {
+            setTitle(mAccessPoint.getConfigName());
+        } else {
+            setTitle(mAccessPoint.getSsid());
+        }
+
+        final Context context = getContext();
+        int level = mAccessPoint.getLevel();
+        if (level != mLevel) {
+            mLevel = level;
+            updateIcon(mLevel, context);
+            notifyChanged();
+        }
+        updateBadge(context);
+
+        setSummary(mForSavedNetworks ? mAccessPoint.getSavedNetworkSummary()
+                : mAccessPoint.getSettingsSummary());
+
+        mContentDescription = getTitle();
+        if (getSummary() != null) {
+            mContentDescription = TextUtils.concat(mContentDescription, ",", getSummary());
+        }
+        if (level >= 0 && level < WIFI_CONNECTION_STRENGTH.length) {
+            mContentDescription = TextUtils.concat(mContentDescription, ",",
+                    getContext().getString(WIFI_CONNECTION_STRENGTH[level]));
+        }
+    }
+
+    @Override
+    protected void notifyChanged() {
+        if (Looper.getMainLooper() != Looper.myLooper()) {
+            // Let our BG thread callbacks call setTitle/setSummary.
+            postNotifyChanged();
+        } else {
+            super.notifyChanged();
+        }
+    }
+
+    public void onLevelChanged() {
+        postNotifyChanged();
+    }
+
+    private void postNotifyChanged() {
+        if (mTitleView != null) {
+            mTitleView.post(mNotifyChanged);
+        } // Otherwise we haven't been bound yet, and don't need to update.
+    }
+
+    private final Runnable mNotifyChanged = new Runnable() {
+        @Override
+        public void run() {
+            notifyChanged();
+        }
+    };
+
+    public static class UserBadgeCache {
+        private final SparseArray<Drawable> mBadges = new SparseArray<>();
+        private final PackageManager mPm;
+
+        public UserBadgeCache(PackageManager pm) {
+            mPm = pm;
+        }
+
+        private Drawable getUserBadge(int userId) {
+            int index = mBadges.indexOfKey(userId);
+            if (index < 0) {
+                Drawable badge = mPm.getUserBadgeForDensity(new UserHandle(userId), 0 /* dpi */);
+                mBadges.put(userId, badge);
+                return badge;
+            }
+            return mBadges.valueAt(index);
+        }
+    }
+}
diff --git a/packages/SettingsProvider/res/values-bs-rBA/defaults.xml b/packages/SettingsProvider/res/values-bs-rBA/defaults.xml
new file mode 100644
index 0000000..5650077
--- /dev/null
+++ b/packages/SettingsProvider/res/values-bs-rBA/defaults.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- no translation found for def_device_name (6309317409634339402) -->
+    <skip />
+    <!-- no translation found for def_device_name_simple (9037785625140748221) -->
+    <skip />
+    <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
+</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index e5aeb3c..d89abf42 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -235,23 +235,27 @@
         // it means that the user has performed a global gesture to enable accessibility or set
         // these settings in the Accessibility portion of the Setup Wizard, and definitely needs
         // these features working after the restore.
-        if (Settings.Secure.ACCESSIBILITY_ENABLED.equals(name)
-                || Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION.equals(name)
-                || Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD.equals(name)
-                || Settings.Secure.TOUCH_EXPLORATION_ENABLED.equals(name)
-                || Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED.equals(name)
-                || Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED.equals(name)
-                || Settings.Secure.UI_NIGHT_MODE.equals(name)) {
-            return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
-        } else if (Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES.equals(name)
-                || Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES.equals(name)
-                || Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX.equals(name)
-                || Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER.equals(name)
-                || Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE.equals(name)) {
-            return !TextUtils.isEmpty(Settings.Secure.getString(
-                    mContext.getContentResolver(), name));
+        switch (name) {
+            case Settings.Secure.ACCESSIBILITY_ENABLED:
+            case Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION:
+            case Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD:
+            case Settings.Secure.TOUCH_EXPLORATION_ENABLED:
+            case Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED:
+            case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED:
+            case Settings.Secure.UI_NIGHT_MODE:
+                return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
+            case Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES:
+            case Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES:
+            case Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX:
+            case Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER:
+            case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE:
+                return !TextUtils.isEmpty(Settings.Secure.getString(
+                        mContext.getContentResolver(), name));
+            case Settings.System.FONT_SCALE:
+                return Settings.System.getFloat(mContext.getContentResolver(), name, 1.0f) != 1.0f;
+            default:
+                return false;
         }
-        return false;
     }
 
     private void setAutoRestore(boolean enabled) {
diff --git a/packages/Shell/res/values-af/strings.xml b/packages/Shell/res/values-af/strings.xml
index d11a499..b9a7c24 100644
--- a/packages/Shell/res/values-af/strings.xml
+++ b/packages/Shell/res/values-af/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Skermkiekie suksesvol geneem."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Kon nie skermkiekie neem nie."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Foutverslagbesonderhede"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-am/strings.xml b/packages/Shell/res/values-am/strings.xml
index cfa22ff..7c5519e 100644
--- a/packages/Shell/res/values-am/strings.xml
+++ b/packages/Shell/res/values-am/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"የሳንካ ሪፖርቶች የግል መረጃን ጨምሮ ከበርካታ የስርዓቱ ምዝግብ ማስታወሻዎች የመጣ ውሂብን ይዟል። የሳንካ ሪፖርቶች ለሚያምኗቸው መተግበሪያዎችን እና ሰዎችን ብቻ ያጋሩ።"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ቅጽበታዊ ገጽ እይታ በስኬት ተነስቷል።"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ቅጽበታዊ ገጽ እይታ ሊነሳ አይችልም"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"የሳንካ ሪፖርት ዝርዝሮች"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"የፋይል ስም"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"ርዕስ"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ዝርዝር መግለጫ"</string>
 </resources>
diff --git a/packages/Shell/res/values-ar/strings.xml b/packages/Shell/res/values-ar/strings.xml
index dc8edba..b1079319 100644
--- a/packages/Shell/res/values-ar/strings.xml
+++ b/packages/Shell/res/values-ar/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"تحتوي تقارير الأخطاء على بيانات من ملفات سجلات النظام المتنوعة، بما في ذلك معلومات شخصية وخاصة. لا تشارك تقارير الأخطاء إلا مع التطبيقات والأشخاص الموثوق بهم."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"تم التقاط لقطة الشاشة بنجاح."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"تعذر التقاط لقطة الشاشة."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"تفاصيل تقرير الخطأ"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"اسم الملف"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"العنوان"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"وصف تفصيلي"</string>
 </resources>
diff --git a/packages/Shell/res/values-az-rAZ/strings.xml b/packages/Shell/res/values-az-rAZ/strings.xml
index b47edc8..d01ae2a 100644
--- a/packages/Shell/res/values-az-rAZ/strings.xml
+++ b/packages/Shell/res/values-az-rAZ/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Displey görüntüsü uğurla çəkildi."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Displey görüntüsü əlçatan deyil."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Baq hesabat detalları"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-b+sr+Latn/strings.xml b/packages/Shell/res/values-b+sr+Latn/strings.xml
index 16f1d28..f39dbcb 100644
--- a/packages/Shell/res/values-b+sr+Latn/strings.xml
+++ b/packages/Shell/res/values-b+sr+Latn/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Snimanje ekrana je uspelo."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snimanje ekrana nije uspelo."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalji izveštaja o grešci"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-bg/strings.xml b/packages/Shell/res/values-bg/strings.xml
index ae60f0b..068bcd3 100644
--- a/packages/Shell/res/values-bg/strings.xml
+++ b/packages/Shell/res/values-bg/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Отчетите за програмни грешки съдържат данни от различни регистрационни файлове на системата, включително лична и поверителна информация. Споделяйте ги само с приложения и хора, на които имате доверие."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Екранната снимка бе направена успешно."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Екранната снимка не можа да бъде направена."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Подробности за сигнала за програмна грешка"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Име на файла"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Заглавие"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Подробно описание"</string>
 </resources>
diff --git a/packages/Shell/res/values-bn-rBD/strings.xml b/packages/Shell/res/values-bn-rBD/strings.xml
index 1192275..e484b47 100644
--- a/packages/Shell/res/values-bn-rBD/strings.xml
+++ b/packages/Shell/res/values-bn-rBD/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"ত্রুটির প্রতিবেদনগুলিতে থাকা ডেটা, সিস্টেমের বিভিন্ন লগ ফাইলগুলি থেকে আসে, যাতে ব্যক্তিগত এবং গোপনীয় তথ্য অন্তর্ভুক্ত থাকে৷ আপনি বিশ্বাস করেন শুধুমাত্র এমন অ্যাপ্লিকেশান এবং ব্যক্তিদের সাথে ত্রুটির প্রতিবেদনগুলি ভাগ করুন৷"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"স্ক্রীনশট সফলভাবে নেওয়া হয়েছে৷"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"স্ক্রীনশট নেওয়া যায়নি৷"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ত্রুটি প্রতিবেদনের বিবরণ"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ফাইলের নাম"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"শীর্ষক"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"বিস্তারিত বিবরণ"</string>
 </resources>
diff --git a/packages/Shell/res/values-bs-rBA/strings.xml b/packages/Shell/res/values-bs-rBA/strings.xml
new file mode 100644
index 0000000..55a9341
--- /dev/null
+++ b/packages/Shell/res/values-bs-rBA/strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="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 />
+</resources>
diff --git a/packages/Shell/res/values-ca/strings.xml b/packages/Shell/res/values-ca/strings.xml
index abf8a6d..14c21da 100644
--- a/packages/Shell/res/values-ca/strings.xml
+++ b/packages/Shell/res/values-ca/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La captura de pantalla s\'ha fet correctament."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"No s\'ha pogut fer la captura de pantalla."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalls de l\'informe d\'errors"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-cs/strings.xml b/packages/Shell/res/values-cs/strings.xml
index b19f50a..19a4453 100644
--- a/packages/Shell/res/values-cs/strings.xml
+++ b/packages/Shell/res/values-cs/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Snímek obrazovky byl úspěšně pořízen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snímek obrazovky se nepodařilo pořídit."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Podrobnosti zprávy o chybě"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-da/strings.xml b/packages/Shell/res/values-da/strings.xml
index df2ba6f..a03276a 100644
--- a/packages/Shell/res/values-da/strings.xml
+++ b/packages/Shell/res/values-da/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Der blev taget et skærmbillede."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Der kunne ikke tages et skærmbillede."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Fejlrapportoplysninger"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-de/strings.xml b/packages/Shell/res/values-de/strings.xml
index b1dab44..4f5e6c5 100644
--- a/packages/Shell/res/values-de/strings.xml
+++ b/packages/Shell/res/values-de/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot wurde aufgenommen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot konnte nicht aufgenommen werden."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Details des Fehlerberichts"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-el/strings.xml b/packages/Shell/res/values-el/strings.xml
index 700869b..71debd7 100644
--- a/packages/Shell/res/values-el/strings.xml
+++ b/packages/Shell/res/values-el/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Οι αναφορές σφαλμάτων περιέχουν δεδομένα από τα διάφορα αρχεία καταγραφής του συστήματος, συμπεριλαμβανομένων προσωπικών και ιδιωτικών πληροφοριών. Να μοιράζεστε αναφορές σφαλμάτων μόνο με εφαρμογές και άτομα που εμπιστεύεστε."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Η λήψη του στιγμιότυπου οθόνης ολοκληρώθηκε με επιτυχία."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Δεν ήταν δυνατή η λήψη του στιγμιότυπου οθόνης."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Λεπτομέρειες αναφοράς σφαλμάτων"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Όνομα αρχείου"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Τίτλος"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Αναλυτική περιγραφή"</string>
 </resources>
diff --git a/packages/Shell/res/values-en-rAU/strings.xml b/packages/Shell/res/values-en-rAU/strings.xml
index dd97cda3..a1bd979 100644
--- a/packages/Shell/res/values-en-rAU/strings.xml
+++ b/packages/Shell/res/values-en-rAU/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot taken successfully."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Bug report details"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-en-rGB/strings.xml b/packages/Shell/res/values-en-rGB/strings.xml
index dd97cda3..a1bd979 100644
--- a/packages/Shell/res/values-en-rGB/strings.xml
+++ b/packages/Shell/res/values-en-rGB/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot taken successfully."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Bug report details"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-en-rIN/strings.xml b/packages/Shell/res/values-en-rIN/strings.xml
index dd97cda3..a1bd979 100644
--- a/packages/Shell/res/values-en-rIN/strings.xml
+++ b/packages/Shell/res/values-en-rIN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot taken successfully."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Bug report details"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-es-rUS/strings.xml b/packages/Shell/res/values-es-rUS/strings.xml
index 3fdf639..f86fea0 100644
--- a/packages/Shell/res/values-es-rUS/strings.xml
+++ b/packages/Shell/res/values-es-rUS/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Se tomó la captura de pantalla correctamente."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"No se pudo tomar la captura de pantalla."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalles del informe de errores"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-es/strings.xml b/packages/Shell/res/values-es/strings.xml
index 2faa948..8f6cdeb 100644
--- a/packages/Shell/res/values-es/strings.xml
+++ b/packages/Shell/res/values-es/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La captura de pantalla se ha realizado correctamente."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"No se puede realizar la captura de pantalla."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalles del informe de errores"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-et-rEE/strings.xml b/packages/Shell/res/values-et-rEE/strings.xml
index 1d59b75..3ebd56d 100644
--- a/packages/Shell/res/values-et-rEE/strings.xml
+++ b/packages/Shell/res/values-et-rEE/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Veaaruanded sisaldavad andmeid erinevatest süsteemi logifailidest, sh isiklikku ja privaatset teavet. Jagage veaaruandeid ainult usaldusväärsete rakenduste ja inimestega."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekraanipildi tegemine õnnestus."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekraanipilti ei saanud teha."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Veaaruande üksikasjad"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-eu-rES/strings.xml b/packages/Shell/res/values-eu-rES/strings.xml
index e85b8cd..93fdb60 100644
--- a/packages/Shell/res/values-eu-rES/strings.xml
+++ b/packages/Shell/res/values-eu-rES/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Atera da pantaila-argazkia."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ezin izan da atera pantaila-argazkia."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Akatsen txostenaren xehetasunak"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-fa/strings.xml b/packages/Shell/res/values-fa/strings.xml
index 591ef0d..c4ec8b4 100644
--- a/packages/Shell/res/values-fa/strings.xml
+++ b/packages/Shell/res/values-fa/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"گزارش‌های اشکال حاوی داده‌هایی از فایل‌های گزارش مختلف در سیستم هستند، شامل اطلاعات شخصی و خصوصی. گزارش‌های اشکال را فقط با افراد و برنامه‌های مورد اعتماد خود به اشتراک بگذارید."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"عکس صفحه‌نمایش با موفقیت گرفته شد."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"نمی‌توان عکس صفحه‌نمایش گرفت."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"جزئیات گزارش اشکال"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"نام فایل"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"عنوان"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"جزئیات دقیق"</string>
 </resources>
diff --git a/packages/Shell/res/values-fi/strings.xml b/packages/Shell/res/values-fi/strings.xml
index 766ff23..0fc4b77 100644
--- a/packages/Shell/res/values-fi/strings.xml
+++ b/packages/Shell/res/values-fi/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Kuvakaappaus tallennettu."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Kuvakaappauksen tallentaminen epäonnistui."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Virheraportin tiedot"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-fr-rCA/strings.xml b/packages/Shell/res/values-fr-rCA/strings.xml
index 8bff08f..d2ef54c 100644
--- a/packages/Shell/res/values-fr-rCA/strings.xml
+++ b/packages/Shell/res/values-fr-rCA/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La saisie d\'écran a réussi."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Une erreur s\'est produite lors de la saisie d\'écran."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Détails du rapport de bogue"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-fr/strings.xml b/packages/Shell/res/values-fr/strings.xml
index 4e5c3c1..ca135ed 100644
--- a/packages/Shell/res/values-fr/strings.xml
+++ b/packages/Shell/res/values-fr/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La capture d\'écran a bien été effectuée."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Impossible d\'effectuer une capture d\'écran."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Détails du rapport de bug"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-gl-rES/strings.xml b/packages/Shell/res/values-gl-rES/strings.xml
index 099f92a..612d346 100644
--- a/packages/Shell/res/values-gl-rES/strings.xml
+++ b/packages/Shell/res/values-gl-rES/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"A captura de pantalla realizouse correctamente."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Non se puido realizar a captura de pantalla."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalles do informe de erros"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-gu-rIN/strings.xml b/packages/Shell/res/values-gu-rIN/strings.xml
index 9943ffb..7baefe7 100644
--- a/packages/Shell/res/values-gu-rIN/strings.xml
+++ b/packages/Shell/res/values-gu-rIN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"બગ રિપોર્ટ્સ વ્યક્તિગત અને ખાનગી માહિતી સહિત, સિસ્ટમની વિભિન્ન લૉગ ફાઇલોનો ડેટા ધરાવે છે. બગ રિપોર્ટ્સ ફક્ત તમે વિશ્વાસ કરતા હો તે એપ્લિકેશનો અને લોકો સાથે જ શેર કરો."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"સ્ક્રીનશોટ સફળતાપૂર્વક લેવાયો."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"સ્ક્રીનશોટ લઇ શકાયો નથી."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"બગ રિપોર્ટની વિગતો"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ફાઇલનું નામ"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"શીર્ષક"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"વિગતવાર વર્ણન"</string>
 </resources>
diff --git a/packages/Shell/res/values-hi/strings.xml b/packages/Shell/res/values-hi/strings.xml
index cf871b6..c21213e 100644
--- a/packages/Shell/res/values-hi/strings.xml
+++ b/packages/Shell/res/values-hi/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"बग रिपोर्ट में व्यक्तिगत और निजी जानकारी सहित, सिस्टम की विभिन्न लॉग फ़ाइलों का डेटा होता है. बग रिपोर्ट केवल विश्वसनीय ऐप्स  और व्यक्तियों से ही साझा करें."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"स्क्रीनशॉट सफलतापूर्वक लिया गया."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट नहीं लिया जा सका."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"बग रिपोर्ट के विवरण"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"फ़ाइल नाम"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"शीर्षक"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"विस्तृत वर्णन"</string>
 </resources>
diff --git a/packages/Shell/res/values-hr/strings.xml b/packages/Shell/res/values-hr/strings.xml
index 5072b6b..810ad3a 100644
--- a/packages/Shell/res/values-hr/strings.xml
+++ b/packages/Shell/res/values-hr/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Zaslon je snimljen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snimanje zaslona nije uspjelo."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Pojedinosti izvješća o programskoj pogrešci"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-hu/strings.xml b/packages/Shell/res/values-hu/strings.xml
index 400cd18..b78fc61 100644
--- a/packages/Shell/res/values-hu/strings.xml
+++ b/packages/Shell/res/values-hu/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Sikerült elkészíteni a képernyőképet."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nem sikerült elkészíteni a képernyőképet."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Hibajelentés részletei"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml
index 2febc7d..4912d54 100644
--- a/packages/Shell/res/values-hy-rAM/strings.xml
+++ b/packages/Shell/res/values-hy-rAM/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Վրիպակի զեկույցները պարունակում են տվյալներ համակարգի տարբեր մուտքի ֆայլերից, այդ թվում նաև անհատական ​​և գաղտնի տեղեկություններ: Վրիպակի զեկույցները կիսեք միայն այն հավելվածների և մարդկանց հետ, որոնց վստահում եք:"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Էկրանի պատկերը հաջողությամբ ստացվեց:"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Չհաջողվեց ստանալ էկրանի պատկերը:"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Վրիպակի զեկույցի մանրամասները"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Ֆայլի անունը"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Անվանումը"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Մանրամասն նկարագրություն"</string>
 </resources>
diff --git a/packages/Shell/res/values-in/strings.xml b/packages/Shell/res/values-in/strings.xml
index 400cb98..e774de9 100644
--- a/packages/Shell/res/values-in/strings.xml
+++ b/packages/Shell/res/values-in/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Tangkapan layar berhasil diambil."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Tangkapan layar tidak dapat diambil."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detail laporan bug"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-is-rIS/strings.xml b/packages/Shell/res/values-is-rIS/strings.xml
index 1886d6e..d175b4f 100644
--- a/packages/Shell/res/values-is-rIS/strings.xml
+++ b/packages/Shell/res/values-is-rIS/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Tókst að taka skjámynd."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekki tókst að taka skjámynd."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Upplýsingar um villutilkynningu"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-it/strings.xml b/packages/Shell/res/values-it/strings.xml
index 39532dc..a954b0c 100644
--- a/packages/Shell/res/values-it/strings.xml
+++ b/packages/Shell/res/values-it/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot acquisito."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Impossibile acquisire lo screenshot."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Dettagli della segnalazione di bug"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-iw/strings.xml b/packages/Shell/res/values-iw/strings.xml
index c950b49..40bd73b 100644
--- a/packages/Shell/res/values-iw/strings.xml
+++ b/packages/Shell/res/values-iw/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"דוחות על באגים כוללים נתונים מקובצי היומן השונים במערכת, כולל מידע אישי ופרטי. שתף דוחות באגים רק עם אפליקציות ואנשים שאתה סומך עליהם."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"צילום המסך בוצע בהצלחה."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"לא ניתן היה לצלם מסך."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"פרטי דוח על באג"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"שם קובץ"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"כותרת"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"תיאור מפורט"</string>
 </resources>
diff --git a/packages/Shell/res/values-ja/strings.xml b/packages/Shell/res/values-ja/strings.xml
index 5fb0abf..f0183b5 100644
--- a/packages/Shell/res/values-ja/strings.xml
+++ b/packages/Shell/res/values-ja/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"バグレポートには、個人の非公開情報など、システムのさまざまなログファイルのデータが含まれます。共有する場合は信頼するアプリとユーザーのみを選択してください。"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"スクリーンショットを撮影しました。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"スクリーンショットを撮影できませんでした。"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"バグレポートの詳細"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ファイル名"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"タイトル"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"詳細説明"</string>
 </resources>
diff --git a/packages/Shell/res/values-ka-rGE/strings.xml b/packages/Shell/res/values-ka-rGE/strings.xml
index 34aa416..a7ad694 100644
--- a/packages/Shell/res/values-ka-rGE/strings.xml
+++ b/packages/Shell/res/values-ka-rGE/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"ხარვეზის ანგარიშები მოიცავს მონაცემებს სხვადასხვა სისტემური ჟურნალის ფაილებიდან, მათ შორის პირად და კონფიდენციალურ ინფორმაციას."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ეკრანის ანაბეჭდი გადაღებულია წარმატებით."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ეკრანის ანაბეჭდის გადაღება ვერ მოხერხდა."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ხარვეზის შესახებ ანგარიშის დეტალები"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ფაილის სახელი"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"სათაური"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"დეტალური აღწერა"</string>
 </resources>
diff --git a/packages/Shell/res/values-kk-rKZ/strings.xml b/packages/Shell/res/values-kk-rKZ/strings.xml
index a736dd8..25a3879 100644
--- a/packages/Shell/res/values-kk-rKZ/strings.xml
+++ b/packages/Shell/res/values-kk-rKZ/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Вирус туралы баянатта жүйеде тіркелген әртүрлі файлдар туралы деректер болады, оған жеке және құпия ақпарат та кіреді. Вирус баянаттарын сенімді қолданбалар және сенімді адамдармен ғана бөлісіңіз."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Скриншот сәтті түсірілді."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Скриншот түсіру мүмкін болмады."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Қате туралы есептің мәліметтері"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Файл атауы"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Атауы"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Егжей-тегжейлі сипаттама"</string>
 </resources>
diff --git a/packages/Shell/res/values-km-rKH/strings.xml b/packages/Shell/res/values-km-rKH/strings.xml
index 128f6e0..844c317 100644
--- a/packages/Shell/res/values-km-rKH/strings.xml
+++ b/packages/Shell/res/values-km-rKH/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"របាយការណ៍​កំហុស​រួមមាន​ឯកសារ​កំណត់​ហេតុ​ផ្សេងៗ​របស់​ប្រព័ន្ធ រួមមាន​ព័ត៌មាន​ផ្ទាល់ខ្លួន និង​ឯកជន។ ចែករំលែក​របាយការណ៍​កំហុស​ជា​មួយ​កម្មវិធី និង​មនុស្ស​ដែល​អ្នក​ទុក​ចិត្ត។"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"បានថតរូបថតអេក្រង់ដោយជោគជ័យ"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"មិនអាចថតរូបថតអេក្រង់បានទេ"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ព័ត៌មានលម្អិតពីរបាយការណ៍កំហុស"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ឈ្មោះ​ឯកសារ"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"ចំណងជើង"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ការពិពណ៌នាលម្អិត"</string>
 </resources>
diff --git a/packages/Shell/res/values-kn-rIN/strings.xml b/packages/Shell/res/values-kn-rIN/strings.xml
index 876e1b4..a3c9b95 100644
--- a/packages/Shell/res/values-kn-rIN/strings.xml
+++ b/packages/Shell/res/values-kn-rIN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"ವೈಯಕ್ತಿಕ ಮತ್ತು ಖಾಸಗಿ ಮಾಹಿತಿಯು ಸೇರಿದಂತೆ, ಸಿಸ್ಟಂನ ಹಲವಾರು ಲಾಗ್ ಫೈಲ್‌ಗಳಿಂದ ಡೇಟಾವನ್ನು ದೋಷದ ವರದಿಗಳು ಒಳಗೊಂಡಿವೆ. ನೀವು ನಂಬುವಂತಹ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ಜನರೊಂದಿಗೆ ಮಾತ್ರ ದೋಷದ ವರದಿಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಿ."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಯಶಸ್ವಿಯಾಗಿ ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ತೆಗೆದುಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ಬಗ್ ವರದಿ ವಿವರಗಳು"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ಫೈಲ್‌ಹೆಸರು"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"ಶೀರ್ಷಿಕೆ"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ವಿವರವಾದ ವಿವರಣೆ"</string>
 </resources>
diff --git a/packages/Shell/res/values-ko/strings.xml b/packages/Shell/res/values-ko/strings.xml
index 80dc6bb..912d940 100644
--- a/packages/Shell/res/values-ko/strings.xml
+++ b/packages/Shell/res/values-ko/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"버그 신고서는 시스템의 다양한 로그 파일 데이터(예: 개인 및 비공개 정보)를 포함합니다. 신뢰할 수 있는 앱과 사용자에게만 버그 신고서를 공유하세요."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"스크린샷을 찍었습니다."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"스크린샷을 찍을 수 없습니다."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"버그 신고 세부정보"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"파일 이름"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"제목"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"자세한 설명"</string>
 </resources>
diff --git a/packages/Shell/res/values-ky-rKG/strings.xml b/packages/Shell/res/values-ky-rKG/strings.xml
index 00be46b..8ad785c 100644
--- a/packages/Shell/res/values-ky-rKG/strings.xml
+++ b/packages/Shell/res/values-ky-rKG/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Ката тууралуу билдирүүлөр системанын ар кандай лог файлдарынын берилиштерин камтыйт, аларга өздүк жана купуя маалыматтар дагы кирет. Ката тууралуу билдирүүлөрдү сиз ишенген колдонмолор жана адамдар менен гана бөлүшүңүз."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Скриншот ийгиликтүү тартылды."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Скриншот тартылбай койду."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Мүчүлүштүктөр жөнүндө кабардын чоо-жайы"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Файлдын аталышы"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Аталышы"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Кененирээк маалымат"</string>
 </resources>
diff --git a/packages/Shell/res/values-lo-rLA/strings.xml b/packages/Shell/res/values-lo-rLA/strings.xml
index 58b3daf..d159254 100644
--- a/packages/Shell/res/values-lo-rLA/strings.xml
+++ b/packages/Shell/res/values-lo-rLA/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"ການລາຍງານຂໍ້ຜິດພາດປະກອບມີ ຂໍ້ມູນຈາກໄຟລ໌ບັນທຶກຂອງລະບົບຫຼາຍໄຟລ໌, ຮວມທັງຂໍ້ມູນສ່ວນໂຕນຳ. ທ່ານຕ້ອງແບ່ງປັນລາຍງານຂໍ້ຜິດພາດໃຫ້ແອັບຯ ແລະຄົນທີ່ທ່ານເຊື່ອຖືໄດ້ເທົ່ານັ້ນ."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ຖ່າຍພາບໜ້າຈໍສຳເລັດແລ້ວ."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ບໍ່ສາມາດຖ່າຍພາບໜ້າຈໍໄດ້."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ລາຍ​ລະ​ອຽດ​ການລາຍງານບັນຫາ"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ຊື່ໄຟລ໌"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"ຊື່"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ຄຳອະທິບາຍແບບລະອຽດ"</string>
 </resources>
diff --git a/packages/Shell/res/values-lt/strings.xml b/packages/Shell/res/values-lt/strings.xml
index 9419ad3..0c069c6 100644
--- a/packages/Shell/res/values-lt/strings.xml
+++ b/packages/Shell/res/values-lt/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekrano kopija sėkmingai padaryta."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nepavyko padaryti ekrano kopijos."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Išsami pranešimo apie riktą informacija"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-lv/strings.xml b/packages/Shell/res/values-lv/strings.xml
index 574fd0b..1baa343 100644
--- a/packages/Shell/res/values-lv/strings.xml
+++ b/packages/Shell/res/values-lv/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekrānuzņēmums ir veikts sekmīgi."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nevarēja veikt ekrānuzņēmumu."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Kļūdas pārskata informācija"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-mk-rMK/strings.xml b/packages/Shell/res/values-mk-rMK/strings.xml
index dc1f249..efbec8e 100644
--- a/packages/Shell/res/values-mk-rMK/strings.xml
+++ b/packages/Shell/res/values-mk-rMK/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Извештаите за грешка содржат податоци од разни датотеки за евиденција на системот, вклучувајќи лични и приватни информации. Извештаите за грешка споделувајте ги само со апликации и луѓе на коишто им верувате."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Успешно е направена слика од екранот."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не може да се направи слика од екранот."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Детали на извештајот за грешка"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Име на датотека"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Наслов"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Детален опис"</string>
 </resources>
diff --git a/packages/Shell/res/values-ml-rIN/strings.xml b/packages/Shell/res/values-ml-rIN/strings.xml
index 7f411a4..82cfd6d 100644
--- a/packages/Shell/res/values-ml-rIN/strings.xml
+++ b/packages/Shell/res/values-ml-rIN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"വ്യക്തിഗതവും സ്വകാര്യവുമായ വിവരങ്ങൾ ഉൾപ്പെടെ, സിസ്റ്റത്തിന്റെ നിരവധി ലോഗ് ഫയലുകളിൽ നിന്നുള്ള ഡാറ്റ, ബഗ് റിപ്പോർട്ടുകളിൽ അടങ്ങിയിരിക്കുന്നു. നിങ്ങൾ വിശ്വസിക്കുന്ന അപ്ലിക്കേഷനുകൾക്കും ആളുകൾക്കും മാത്രം ബഗ് റിപ്പോർട്ടുകൾ പങ്കിടുക."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"സ്ക്രീൻഷോട്ട് എടുത്തു."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"സ്ക്രീൻഷോട്ട് എടുക്കാൻ കഴിഞ്ഞില്ല."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ബഗ് റിപ്പോർട്ട് വിശദാംശങ്ങൾ"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ഫയല്‍നാമം"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"പേര്"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"വിശദമായ വിവരണം"</string>
 </resources>
diff --git a/packages/Shell/res/values-mn-rMN/strings.xml b/packages/Shell/res/values-mn-rMN/strings.xml
index 1f47fbf..856803d 100644
--- a/packages/Shell/res/values-mn-rMN/strings.xml
+++ b/packages/Shell/res/values-mn-rMN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Алдааны репорт нь хувийн болон нууц мэдээлэл зэргийг агуулсан системийн төрөл бүрийн лог файлын датаг агуулна. Алдааны репортыг зөвхөн итгэлтэй апп болон хүмүүст хуваалцана уу."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Дэлгэцийн зургийг амжилттай авлаа."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Дэлгэцийн зураг авах боломжгүй."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Алдааны дэлгэрэнгүй тайлан"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Файлын нэр"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Гарчиг"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Дэлгэрэнгүй тайлбар"</string>
 </resources>
diff --git a/packages/Shell/res/values-mr-rIN/strings.xml b/packages/Shell/res/values-mr-rIN/strings.xml
index 89c9275..763eec6 100644
--- a/packages/Shell/res/values-mr-rIN/strings.xml
+++ b/packages/Shell/res/values-mr-rIN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"दोष अहवालांमध्‍ये वैयक्तिक आणि खाजगी माहितीसह, सिस्‍टमच्‍या अनेक लॉग फायलींमधील डेटा असतो. केवळ आपला विश्वास असलेल्‍या अ‍ॅप्‍स आणि लोकांसह दोष अहवाल सामायिक करा."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"स्क्रीनशॉट यशस्वीपणे घेतला."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट घेणे शक्य झाले नाही."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"दोष अहवाल तपशील"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"फाईलनाव"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"शीर्षक"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"तपशीलवार वर्णन"</string>
 </resources>
diff --git a/packages/Shell/res/values-ms-rMY/strings.xml b/packages/Shell/res/values-ms-rMY/strings.xml
index c588a05..1afe430 100644
--- a/packages/Shell/res/values-ms-rMY/strings.xml
+++ b/packages/Shell/res/values-ms-rMY/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Tangkapan skrin berjaya diambil."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Tangkapan skrin tidak dapat diambil."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Butiran laporan pepijat"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-my-rMM/strings.xml b/packages/Shell/res/values-my-rMM/strings.xml
index 728eb98..e941111 100644
--- a/packages/Shell/res/values-my-rMM/strings.xml
+++ b/packages/Shell/res/values-my-rMM/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"အမှားအယွင်း မှတ်တမ်းမှာ ပါရှိသော အချက်အလက်များမှာ ကိုယ်ရေးကိုယ်တာ နဲ့ လုံခြုံရေး အချက်အလက်များပါဝင်သော စနစ်မှ ပြုလုပ်မှု မှတ်တမ်းများ ဖြစ်ပါသည်၊ အမှားအယွင်း မှတ်တမ်းများကို ယုံကြည်ရသော အပလီကေးရှင်းများနဲ့ လူများကိုသာ ပေးဝေပြသမှု လုပ်ပါရန်။"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံကို အောင်မြင်စွာ ရိုက်ပြီးပြီ။"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံ မရိုက်နိုင်ပါ"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ချွတ်ယွင်းချက်အစီရင်ခံစာ အသေးစိတ်များ"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ဖိုင်အမည်"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"ခေါင်းစဉ်"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"အသေးစိတ် ဖော်ပြချက်"</string>
 </resources>
diff --git a/packages/Shell/res/values-nb/strings.xml b/packages/Shell/res/values-nb/strings.xml
index dff2a83..87b3530 100644
--- a/packages/Shell/res/values-nb/strings.xml
+++ b/packages/Shell/res/values-nb/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Skjermdumpen er tatt."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Skjermdumpen kunne ikke tas."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detaljer om feilrapporten"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-ne-rNP/strings.xml b/packages/Shell/res/values-ne-rNP/strings.xml
index ec87f35..5b68ece 100644
--- a/packages/Shell/res/values-ne-rNP/strings.xml
+++ b/packages/Shell/res/values-ne-rNP/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"बग रिपोर्टहरूमा प्रणालीका विभिन्न लग फाइलहरूबाट व्यक्तिगत तथा नीजि सूचनासहितको डेटा रहन्छ।  बग रिपोर्टहरू अनुप्रयोगहरू र तपाईँले विश्वास गरेका व्यक्तिहरूसँग मात्र साझेदारी गर्नुहोस्।"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"स्क्रिनशट सफलतापूर्वक लिइयो।"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रिनशट लिन सकिएन।"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"बग रिपोर्टको विवरण"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"फाइलको नाम"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"शीर्षक"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"विस्तृत विवरण"</string>
 </resources>
diff --git a/packages/Shell/res/values-nl/strings.xml b/packages/Shell/res/values-nl/strings.xml
index b700af5..dd67ccd 100644
--- a/packages/Shell/res/values-nl/strings.xml
+++ b/packages/Shell/res/values-nl/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot is gemaakt."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot kan niet worden gemaakt."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Details van bugrapport"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-pa-rIN/strings.xml b/packages/Shell/res/values-pa-rIN/strings.xml
index 15833be..96addbf 100644
--- a/packages/Shell/res/values-pa-rIN/strings.xml
+++ b/packages/Shell/res/values-pa-rIN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"ਬਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਸਿਸਟਮ ਦੀਆਂ ਭਿੰਨ ਲੌਗ ਫਾਈਲਾਂ ਦਾ ਡਾਟਾ ਹੁੰਦਾ ਹੈ, ਨਿੱਜੀ ਅਤੇ ਪ੍ਰਾਈਵੇਟ ਜਾਣਕਾਰੀ ਸਮੇਤ। ਕੇਵਲ ਉਹਨਾਂ ਐਪਸ ਅਤੇ ਲੋਕਾਂ ਨਾਲ ਬਗ ਰਿਪੋਰਟਾਂ ਸ਼ੇਅਰ ਕਰੋ, ਜਿਹਨਾਂ ਤੇ ਤੁਸੀਂ ਭਰੋਸਾ ਕਰਦੇ ਹੋ।"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਫਲਤਾਪੂਰਵਕ ਲਿਆ ਗਿਆ।"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲਿਆ ਜਾ ਸਕਿਆ।"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ਬੱਗ ਰਿਪੋਰਟ ਵੇਰਵੇ"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ਫ਼ਾਈਲ ਨਾਮ"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"ਸਿਰਲੇਖ"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ਵਿਸਥਾਰ ਸਹਿਤ ਵਰਣਨ"</string>
 </resources>
diff --git a/packages/Shell/res/values-pl/strings.xml b/packages/Shell/res/values-pl/strings.xml
index 9985a91..7a67ac6 100644
--- a/packages/Shell/res/values-pl/strings.xml
+++ b/packages/Shell/res/values-pl/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Zrobiono zrzut ekranu."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nie udało się zrobić zrzutu ekranu."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Szczegóły zgłoszenia błędu"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-pt-rBR/strings.xml b/packages/Shell/res/values-pt-rBR/strings.xml
index 745efb3..471e959 100644
--- a/packages/Shell/res/values-pt-rBR/strings.xml
+++ b/packages/Shell/res/values-pt-rBR/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de tela concluída."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Não foi possível fazer a captura de tela."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalhes do relatório do bug"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-pt-rPT/strings.xml b/packages/Shell/res/values-pt-rPT/strings.xml
index 9252068..ed78f55 100644
--- a/packages/Shell/res/values-pt-rPT/strings.xml
+++ b/packages/Shell/res/values-pt-rPT/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de ecrã tirada com êxito."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Não foi possível tirar a captura de ecrã."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalhes do relatório de erro"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-pt/strings.xml b/packages/Shell/res/values-pt/strings.xml
index 745efb3..471e959 100644
--- a/packages/Shell/res/values-pt/strings.xml
+++ b/packages/Shell/res/values-pt/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de tela concluída."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Não foi possível fazer a captura de tela."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalhes do relatório do bug"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-ro/strings.xml b/packages/Shell/res/values-ro/strings.xml
index 77a6cfd..af67bc6 100644
--- a/packages/Shell/res/values-ro/strings.xml
+++ b/packages/Shell/res/values-ro/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de ecran a fost făcută."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Captura de ecran nu a putut fi făcută."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalii privind raportul de eroare"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-ru/strings.xml b/packages/Shell/res/values-ru/strings.xml
index 18502cf..a5e2bd2 100644
--- a/packages/Shell/res/values-ru/strings.xml
+++ b/packages/Shell/res/values-ru/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Отчеты об ошибках содержат данные различных системных журналов и могут включать личную информацию. Рекомендуем открывать к ним доступ только лицам и приложениям, заслуживающим доверие."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Скриншот готов"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не удалось сделать скриншот"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Детали отчета об ошибке"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Название файла"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Название"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Подробное описание"</string>
 </resources>
diff --git a/packages/Shell/res/values-si-rLK/strings.xml b/packages/Shell/res/values-si-rLK/strings.xml
index 25bef76..866c0f7 100644
--- a/packages/Shell/res/values-si-rLK/strings.xml
+++ b/packages/Shell/res/values-si-rLK/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"පුද්ගලික සහ පෞද්ගලික තොරතුරු ඇතුළත්ව පද්ධතියේ විවිධ ලොග් ගොනු වල දත්ත දෝෂ වාර්තාවේ අඩංගු වේ. ඔබට විශ්වාසවන්ත යෙදුම් සහ පුද්ගලයින් සමඟ පමණක් දෝෂ වාර්තා බෙදා ගන්න."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"සාර්ථකව තිර රුවක් ගන්නා ලදී."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"තිර රුවක් ගත නොහැකි විය."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"දෝෂ වාර්තා විස්තර"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ගොනුවේ නම"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"මාතෘකාව"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"සවිස්තර විස්තරය"</string>
 </resources>
diff --git a/packages/Shell/res/values-sk/strings.xml b/packages/Shell/res/values-sk/strings.xml
index d874169..f207480 100644
--- a/packages/Shell/res/values-sk/strings.xml
+++ b/packages/Shell/res/values-sk/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Snímka obrazovky bola zaznamenaná."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snímku obrazovky sa nepodarilo zaznamenať."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Podrobnosti hlásenia chyby"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-sl/strings.xml b/packages/Shell/res/values-sl/strings.xml
index f7ccc4b..c249961 100644
--- a/packages/Shell/res/values-sl/strings.xml
+++ b/packages/Shell/res/values-sl/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Posnetek zaslon je bil uspešno ustvarjen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Posnetka zaslon ni bilo mogoče ustvariti."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Podrobnosti o poročilu o napakah"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-sq-rAL/strings.xml b/packages/Shell/res/values-sq-rAL/strings.xml
index 529caf8..8a306b3 100644
--- a/packages/Shell/res/values-sq-rAL/strings.xml
+++ b/packages/Shell/res/values-sq-rAL/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Pamja e ekranit u realizua me sukses."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Pamja e ekranit nuk mund të realizohej."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detajet e raportimit të gabimeve në kod"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-sr/strings.xml b/packages/Shell/res/values-sr/strings.xml
index 740d2fb..9bff65c 100644
--- a/packages/Shell/res/values-sr/strings.xml
+++ b/packages/Shell/res/values-sr/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Извештаји о грешкама садрже податке из различитих системских датотека евиденције, укључујући личне и приватне податке. Делите извештаје о грешкама само са апликацијама и људима у које имате поверења."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Снимање екрана је успело."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Снимање екрана није успело."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Детаљи извештаја о грешци"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Назив датотеке"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Наслов"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Детаљни опис"</string>
 </resources>
diff --git a/packages/Shell/res/values-sv/strings.xml b/packages/Shell/res/values-sv/strings.xml
index 1df2110..fb962bf 100644
--- a/packages/Shell/res/values-sv/strings.xml
+++ b/packages/Shell/res/values-sv/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"En skärmdump har tagits."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Det gick inte att ta skrämdump."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Information för felrapporten"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-sw/strings.xml b/packages/Shell/res/values-sw/strings.xml
index bb7364d..de46414 100644
--- a/packages/Shell/res/values-sw/strings.xml
+++ b/packages/Shell/res/values-sw/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Imepiga picha ya skrini."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Haikupiga picha ya skrini."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Maelezo kuhusu ripoti ya hitilafu"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-ta-rIN/strings.xml b/packages/Shell/res/values-ta-rIN/strings.xml
index 28e884f..15c7014 100644
--- a/packages/Shell/res/values-ta-rIN/strings.xml
+++ b/packages/Shell/res/values-ta-rIN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"பிழை அறிக்கைகளில், சொந்த வாழ்க்கை மற்றும் தனிப்பட்ட தகவல் உள்பட கணினியின் பல்வேறு பதிவுகளில் உள்ள தரவு இருக்கும். நீங்கள் நம்பும் பயன்பாடுகள் மற்றும் நபர்களுடன் மட்டும் பிழை அறிக்கைகளைப் பகிரவும்."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ஸ்கிரீன் ஷாட் எடுக்கப்பட்டது."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ஸ்கிரீன் ஷாட்டை எடுக்க முடியவில்லை."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"பிழை அறிக்கை விவரங்கள்"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"கோப்புப்பெயர்"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"தலைப்பு"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"விரிவான விளக்கம்"</string>
 </resources>
diff --git a/packages/Shell/res/values-te-rIN/strings.xml b/packages/Shell/res/values-te-rIN/strings.xml
index 71e3838..c84ec9a 100644
--- a/packages/Shell/res/values-te-rIN/strings.xml
+++ b/packages/Shell/res/values-te-rIN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"బగ్ నివేదికలు వ్యక్తిగతమైన మరియు రహస్యమైన సమాచారంతో సహా సిస్టమ్ యొక్క విభిన్న లాగ్ ఫైల్‌ల్లోని డేటాను కలిగి ఉంటాయి. కనుక బగ్ నివేదికలను మీరు విశ్వసించే అనువర్తనాలు మరియు వ్యక్తులతో మాత్రమే భాగస్వామ్యం చేయండి."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"స్క్రీన్‌షాట్ విజయవంతంగా తీయబడింది."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"స్క్రీన్‌షాట్‌ను తీయడం సాధ్యపడలేదు."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"బగ్ నివేదిక వివరాలు"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ఫైల్ పేరు"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"శీర్షిక"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"సమగ్ర వివరణ"</string>
 </resources>
diff --git a/packages/Shell/res/values-th/strings.xml b/packages/Shell/res/values-th/strings.xml
index fd2749d..f29978e 100644
--- a/packages/Shell/res/values-th/strings.xml
+++ b/packages/Shell/res/values-th/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"รายงานข้อบกพร่องมีข้อมูลจากไฟล์บันทึกต่างๆ ของระบบ รวมถึงข้อมูลส่วนตัว แชร์รายงานข้อบกพร่องกับแอปและบุคคลที่คุณไว้ใจเท่านั้น"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"จับภาพหน้าจอสำเร็จแล้ว"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ไม่สามารถจับภาพหน้าจอได้"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"รายละเอียดรายงานข้อบกพร่อง"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"ชื่อไฟล์"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"ชื่อ"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"คำอธิบายโดยละเอียด"</string>
 </resources>
diff --git a/packages/Shell/res/values-tl/strings.xml b/packages/Shell/res/values-tl/strings.xml
index 3301113..c12191a 100644
--- a/packages/Shell/res/values-tl/strings.xml
+++ b/packages/Shell/res/values-tl/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Nakunan ng screenshot."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Hindi makunan ng screenshot."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Mga detalye ng ulat ng bug"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-tr/strings.xml b/packages/Shell/res/values-tr/strings.xml
index 746458d..3f562d7 100644
--- a/packages/Shell/res/values-tr/strings.xml
+++ b/packages/Shell/res/values-tr/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekran görüntüsü başarıyla alındı."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekran görüntüsü alınamadı."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Hata raporu ayrıntıları"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-uk/strings.xml b/packages/Shell/res/values-uk/strings.xml
index 1f6210e..93e6511 100644
--- a/packages/Shell/res/values-uk/strings.xml
+++ b/packages/Shell/res/values-uk/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"Звіти про помилки містять дані з різних файлів журналу системи, зокрема особисті та конфіденційні. Надсилайте звіт про помилки лише тим, кому довіряєте."</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Знімок екрана зроблено."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не вдалося зробити знімок екрана."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Деталі повідомлення про помилку"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Назва файлу"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Назва"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Детальний опис"</string>
 </resources>
diff --git a/packages/Shell/res/values-ur-rPK/strings.xml b/packages/Shell/res/values-ur-rPK/strings.xml
index 1f09245..52a45a0 100644
--- a/packages/Shell/res/values-ur-rPK/strings.xml
+++ b/packages/Shell/res/values-ur-rPK/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"بَگ رپورٹس میں سسٹم کی مختلف لاگ فائلوں سے ڈیٹا شامل ہوتا ہے، بشمول ذاتی اور نجی معلومات۔ بَگ رپورٹس کا اشتراک صرف اپنے بھروسے مند ایپس اور لوگوں کے ساتھ کریں۔"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"اسکرین شاٹ کامیابی سے لے لیا گیا۔"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"سکرین شاٹ نہیں لیا جا سکا۔"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"بگ رپورٹ کی تفصیلات"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"فائل کا نام"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"عنوان"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"تفصیلی وضاحت"</string>
 </resources>
diff --git a/packages/Shell/res/values-uz-rUZ/strings.xml b/packages/Shell/res/values-uz-rUZ/strings.xml
index 1cf320a..56e0965 100644
--- a/packages/Shell/res/values-uz-rUZ/strings.xml
+++ b/packages/Shell/res/values-uz-rUZ/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Skrinshot tayyor."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Skrinshot olib bo‘lmadi."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Xatoliklar hisoboti tafsilotlari"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-vi/strings.xml b/packages/Shell/res/values-vi/strings.xml
index 4d7a89f..2642b89 100644
--- a/packages/Shell/res/values-vi/strings.xml
+++ b/packages/Shell/res/values-vi/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Đã chụp ảnh màn hình thành công."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Không thể chụp ảnh màn hình."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Chi tiết báo cáo lỗi"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/res/values-zh-rCN/strings.xml b/packages/Shell/res/values-zh-rCN/strings.xml
index ec418b3..c933961 100644
--- a/packages/Shell/res/values-zh-rCN/strings.xml
+++ b/packages/Shell/res/values-zh-rCN/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"错误报告包含的数据来自于系统的各个日志文件,其中包含个人信息和隐私信息。请务必只与您信任的应用和用户分享错误报告。"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"已成功截图。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"无法截图。"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"错误报告详细信息"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"文件名"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"标题"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"详细说明"</string>
 </resources>
diff --git a/packages/Shell/res/values-zh-rHK/strings.xml b/packages/Shell/res/values-zh-rHK/strings.xml
index 7539755..7a35eef 100644
--- a/packages/Shell/res/values-zh-rHK/strings.xml
+++ b/packages/Shell/res/values-zh-rHK/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"錯誤報告中有來自系統各個記錄檔案的資料,包括個人和私人資料。請只與您信任的應用程式和使用者分享錯誤報告。"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"成功拍攝螢幕擷取畫面。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法擷取螢幕畫面。"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"錯誤報告詳情"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"檔案名稱"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"標題"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"詳細說明"</string>
 </resources>
diff --git a/packages/Shell/res/values-zh-rTW/strings.xml b/packages/Shell/res/values-zh-rTW/strings.xml
index 6c2834f..ec66878 100644
--- a/packages/Shell/res/values-zh-rTW/strings.xml
+++ b/packages/Shell/res/values-zh-rTW/strings.xml
@@ -19,6 +19,8 @@
     <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_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_confirm" msgid="5130698467795669780">"錯誤報告的資料來自系統各個紀錄檔,包括個人和私密資訊。請務必只與您信任的應用程式和使用者分享錯誤報告。"</string>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"已成功拍攝螢幕擷取畫面。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法拍攝螢幕擷取畫面。"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"錯誤報告詳細資料"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <string name="bugreport_info_name" msgid="4414036021935139527">"檔案名稱"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"標題"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"詳細說明"</string>
 </resources>
diff --git a/packages/Shell/res/values-zu/strings.xml b/packages/Shell/res/values-zu/strings.xml
index 60592b5..c264224 100644
--- a/packages/Shell/res/values-zu/strings.xml
+++ b/packages/Shell/res/values-zu/strings.xml
@@ -19,6 +19,8 @@
     <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_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_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>
@@ -31,9 +33,7 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Isithombe-skrini sithathwe ngempumelelo."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Isithombe-skrini asikwazanga ukuthathwa."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Imininingwane yombiko wesiphazamisi"</string>
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
+    <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>
 </resources>
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index 52e1b56..5908d02 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -461,6 +461,7 @@
      */
     private void sendBugreportStarted(int max) throws Exception {
         Intent intent = new Intent(INTENT_BUGREPORT_STARTED);
+        intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         intent.putExtra(EXTRA_PID, PID);
         intent.putExtra(EXTRA_NAME, NAME);
         intent.putExtra(EXTRA_MAX, max);
@@ -518,6 +519,7 @@
      */
     private void sendBugreportFinished(Integer pid, String bugreportPath, String screenshotPath) {
         Intent intent = new Intent(INTENT_BUGREPORT_FINISHED);
+        intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         if (pid != null) {
             intent.putExtra(EXTRA_PID, pid);
         }
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 61cad2f..e4d0fec 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -11,7 +11,8 @@
     android-support-v7-recyclerview \
     android-support-v7-preference \
     android-support-v7-appcompat \
-    android-support-v14-preference
+    android-support-v14-preference \
+    framework-protos
 
 LOCAL_JAVA_LIBRARIES := telephony-common
 
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 4cdfcb4..21abb90 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -229,7 +229,7 @@
                   android:resumeWhilePausing="true"
                   android:screenOrientation="behind"
                   android:resizeableActivity="true"
-                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|layoutDirection"
+                  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
                   android:theme="@style/RecentsTheme.Wallpaper">
             <intent-filter>
                 <action android:name="com.android.systemui.recents.TOGGLE_RECENTS" />
@@ -321,7 +321,7 @@
             android:exported="true"
             android:theme="@style/PipTheme"
             android:launchMode="singleTop"
-            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|layoutDirection"
+            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
             android:resizeable="true"
             android:supportsPictureInPicture="true"
             androidprv:alwaysFocusable="true"
@@ -331,7 +331,7 @@
             android:exported="true"
             android:theme="@style/PipTheme"
             android:launchMode="singleTop"
-            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|layoutDirection"
+            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
             android:resizeable="true"
             android:supportsPictureInPicture="true"
             android:excludeFromRecents="true" />
diff --git a/packages/SystemUI/res/drawable/brightness_mirror_background.xml b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
index fadfe63..e901e40 100644
--- a/packages/SystemUI/res/drawable/brightness_mirror_background.xml
+++ b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
@@ -16,9 +16,4 @@
   -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
     <solid android:color="@color/system_primary_color" />
-    <corners
-        android:topLeftRadius="@dimen/notification_material_rounded_rect_radius"
-        android:topRightRadius="@dimen/notification_material_rounded_rect_radius"
-        android:bottomLeftRadius="@dimen/notification_material_rounded_rect_radius"
-        android:bottomRightRadius="@dimen/notification_material_rounded_rect_radius"/>
 </shape>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver.xml b/packages/SystemUI/res/drawable/ic_data_saver.xml
new file mode 100644
index 0000000..426238c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_data_saver.xml
@@ -0,0 +1,28 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="
+        M9.0,16.0l2.0,0.0L11.0,8.0L9.0,8.0l0.0,8.0z
+        m3.0,-14.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0z
+        m0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0z
+        m1.0,-4.0l2.0,0.0l0.0,-8.0l-2.0,0.0l0.0,8.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver_off.xml b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
new file mode 100644
index 0000000..0713548
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
@@ -0,0 +1,28 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#4DFFFFFF"
+        android:pathData="
+        M9.0,16.0l2.0,0.0L11.0,8.0L9.0,8.0l0.0,8.0z
+        m3.0,-14.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0z
+        m0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0z
+        m1.0,-4.0l2.0,0.0l0.0,-8.0l-2.0,0.0l0.0,8.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
new file mode 100644
index 0000000..b4144a3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_data_disabled.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="40.0"
+        android:viewportHeight="40.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19.0,6.41L17.59,5.0 12.0,10.59 6.41,5.0 5.0,6.41 10.59,12.0 5.0,17.59 6.41,19.0 12.0,13.41 17.59,19.0 19.0,17.59 13.41,12.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/notification_material_bg.xml b/packages/SystemUI/res/drawable/notification_material_bg.xml
index 6a0277f..ae45663 100644
--- a/packages/SystemUI/res/drawable/notification_material_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_material_bg.xml
@@ -20,7 +20,6 @@
     <item>
         <shape>
             <solid android:color="@color/notification_material_background_color" />
-            <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
         </shape>
     </item>
 </ripple>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/notification_material_bg_dim.xml b/packages/SystemUI/res/drawable/notification_material_bg_dim.xml
index 6581942..b6a8b70 100644
--- a/packages/SystemUI/res/drawable/notification_material_bg_dim.xml
+++ b/packages/SystemUI/res/drawable/notification_material_bg_dim.xml
@@ -18,7 +18,6 @@
     <item>
         <shape>
             <solid android:color="@color/notification_material_background_dimmed_color" />
-            <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
         </shape>
     </item>
 </ripple>
diff --git a/packages/SystemUI/res/drawable/qs_background_primary.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
index 686df2c..1bf7d4c 100644
--- a/packages/SystemUI/res/drawable/qs_background_primary.xml
+++ b/packages/SystemUI/res/drawable/qs_background_primary.xml
@@ -13,10 +13,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetTop="@dimen/notification_material_rounded_rect_radius_negative">
+<inset xmlns:android="http://schemas.android.com/apk/res/android">
     <shape>
         <solid android:color="@color/system_primary_color"/>
-        <corners android:radius="@dimen/notification_material_rounded_rect_radius"/>
     </shape>
 </inset>
diff --git a/packages/SystemUI/res/drawable/qs_background_secondary.xml b/packages/SystemUI/res/drawable/qs_background_secondary.xml
index 3662e5a..31c0162 100644
--- a/packages/SystemUI/res/drawable/qs_background_secondary.xml
+++ b/packages/SystemUI/res/drawable/qs_background_secondary.xml
@@ -17,7 +17,5 @@
     <solid android:color="@color/system_secondary_color" />
     <corners
         android:topLeftRadius="0dp"
-        android:topRightRadius="0dp"
-        android:bottomLeftRadius="@dimen/notification_material_rounded_rect_radius"
-        android:bottomRightRadius="@dimen/notification_material_rounded_rect_radius"/>
+        android:topRightRadius="0dp" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_disabled.xml b/packages/SystemUI/res/drawable/stat_sys_data_disabled.xml
new file mode 100644
index 0000000..4e2a024
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_disabled.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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="17.0dp"
+        android:height="17.0dp"
+        android:viewportWidth="40.0"
+        android:viewportHeight="40.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19.0,6.41L17.59,5.0 12.0,10.59 6.41,5.0 5.0,6.41 10.59,12.0 5.0,17.59 6.41,19.0 12.0,13.41 17.59,19.0 19.0,17.59 13.41,12.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/volume_dialog_background.xml b/packages/SystemUI/res/drawable/volume_dialog_background.xml
index f09c01b..e98bfb8 100644
--- a/packages/SystemUI/res/drawable/volume_dialog_background.xml
+++ b/packages/SystemUI/res/drawable/volume_dialog_background.xml
@@ -14,9 +14,5 @@
      limitations under the License.
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android" >
-
     <solid android:color="@color/system_primary_color" />
-
-    <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
-
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_layout_rot90.xml b/packages/SystemUI/res/layout-sw600dp/navigation_layout_rot90.xml
index dd559c5..38265f6 100644
--- a/packages/SystemUI/res/layout-sw600dp/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout-sw600dp/navigation_layout_rot90.xml
@@ -25,10 +25,9 @@
         android:layout_height="match_parent">
 
         <LinearLayout
-            android:id="@+id/start_group"
+            android:id="@+id/ends_group"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:gravity="start"
             android:orientation="horizontal" />
 
         <LinearLayout
@@ -38,13 +37,6 @@
             android:gravity="center"
             android:orientation="horizontal" />
 
-        <LinearLayout
-            android:id="@+id/end_group"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:gravity="end"
-            android:orientation="horizontal" />
-
     </FrameLayout>
 
     <FrameLayout
@@ -53,10 +45,9 @@
         android:layout_height="match_parent">
 
         <LinearLayout
-            android:id="@+id/start_group_lightsout"
+            android:id="@+id/ends_group_lightsout"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:gravity="start"
             android:orientation="horizontal" />
 
         <LinearLayout
@@ -66,13 +57,6 @@
             android:gravity="center"
             android:orientation="horizontal" />
 
-        <LinearLayout
-            android:id="@+id/end_group_lightsout"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:gravity="end"
-            android:orientation="horizontal" />
-
     </FrameLayout>
 
     <com.android.systemui.statusbar.policy.DeadZone
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
index b953ff2..6e4b213 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -33,19 +33,19 @@
             android:paddingTop="@dimen/car_lockscreen_disclaimer_title_padding_top" />
         <TextView
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_height="0dp"
+            android:layout_weight="1"
             android:text="@string/car_lockscreen_disclaimer_text"
             android:textSize="@dimen/car_lockscreen_disclaimer_text_size"
             android:paddingStart="@dimen/car_lockscreen_disclaimer_text_padding_start"
             android:paddingEnd="@dimen/car_lockscreen_disclaimer_text_padding_end"
             android:paddingTop="@dimen/car_lockscreen_disclaimer_text_padding_top" />
-        <com.android.systemui.statusbar.UserGridView
+        <com.android.systemui.statusbar.car.UserGridView
             android:id="@+id/user_grid"
             android:layout_gravity="center"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:paddingTop="@dimen/car_lockscreen_user_grid_view_padding_top"
             android:stretchMode="columnWidth">
-        </com.android.systemui.statusbar.UserGridView>
+        </com.android.systemui.statusbar.car.UserGridView>
     </LinearLayout>
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/car_navigation_button.xml b/packages/SystemUI/res/layout/car_navigation_button.xml
index 479f18d..7677646 100644
--- a/packages/SystemUI/res/layout/car_navigation_button.xml
+++ b/packages/SystemUI/res/layout/car_navigation_button.xml
@@ -26,9 +26,10 @@
     <com.android.keyguard.AlphaOptimizedImageButton
             android:id="@+id/car_nav_button_icon"
             android:layout_height="match_parent"
-            android:layout_width="wrap_content"
+            android:layout_width="@dimen/car_navigation_button_width"
             android:layout_centerInParent="true"
-            android:animateLayoutChanges="true">
+            android:animateLayoutChanges="true"
+            android:scaleType="fitCenter">
     </com.android.keyguard.AlphaOptimizedImageButton>
 
     <com.android.keyguard.AlphaOptimizedImageButton
@@ -37,6 +38,7 @@
             android:layout_width="wrap_content"
             android:layout_centerVertical="true"
             android:layout_toRightOf="@+id/car_nav_button_icon"
-            android:animateLayoutChanges="true">
+            android:animateLayoutChanges="true"
+            android:scaleType="fitCenter">
     </com.android.keyguard.AlphaOptimizedImageButton>
 </com.android.systemui.statusbar.car.CarNavigationButton>
diff --git a/packages/SystemUI/res/layout/navigation_bar_with_apps.xml b/packages/SystemUI/res/layout/navigation_bar_with_apps.xml
deleted file mode 100644
index ac95b5e..0000000
--- a/packages/SystemUI/res/layout/navigation_bar_with_apps.xml
+++ /dev/null
@@ -1,331 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
--->
-
-<!-- Navigation bar with app shortcuts. See also navigation_bar.xml. -->
-<com.android.systemui.statusbar.phone.NavigationBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@drawable/system_bar_background"
-    >
-
-    <!-- Portrait layout. -->
-    <FrameLayout android:id="@+id/rot0"
-        android:layout_height="match_parent"
-        android:layout_width="match_parent"
-        >
-
-        <LinearLayout
-            android:layout_height="match_parent"
-            android:layout_width="match_parent"
-            android:orientation="horizontal"
-            android:clipChildren="false"
-            android:clipToPadding="false"
-            android:id="@+id/nav_buttons"
-            android:animateLayoutChanges="true"
-            >
-
-            <!-- Back button is flush left. -->
-            <com.android.systemui.statusbar.policy.KeyButtonView
-                android:id="@+id/back"
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_back"
-                android:scaleType="centerInside"
-                systemui:keyCode="4"
-                android:layout_weight="0"
-                android:contentDescription="@string/accessibility_back"
-                />
-
-            <com.android.systemui.statusbar.policy.KeyButtonView
-                android:id="@+id/home"
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_home"
-                android:scaleType="centerInside"
-                systemui:keyCode="3"
-                systemui:keyRepeat="true"
-                android:layout_weight="0"
-                android:contentDescription="@string/accessibility_home"
-                />
-
-            <!-- Container for the app shelf. -->
-            <LinearLayout
-                android:id="@+id/app_shelf"
-                android:orientation="horizontal"
-                android:layout_height="match_parent"
-                android:layout_width="0dp"
-                android:layout_weight="1"
-                >
-                <com.android.systemui.statusbar.phone.NavigationBarApps
-                    android:id="@+id/navigation_bar_apps"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    />
-            </LinearLayout>
-
-            <FrameLayout
-                android:layout_width="@dimen/navigation_extra_key_width"
-                android:layout_height="match_parent"
-                android:layout_weight="0"
-                android:layout_marginEnd="2dp" >
-                <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
-                    android:layout_width="@dimen/navigation_extra_key_width"
-                    android:layout_height="match_parent"
-                    android:src="@drawable/ic_sysbar_menu"
-                    android:scaleType="centerInside"
-                    android:layout_marginEnd="2dp"
-                    systemui:keyCode="82"
-                    android:visibility="invisible"
-                    android:contentDescription="@string/accessibility_menu"
-                    />
-                <com.android.systemui.statusbar.policy.KeyButtonView
-                    android:id="@+id/ime_switcher"
-                    android:layout_width="@dimen/navigation_extra_key_width"
-                    android:layout_height="match_parent"
-                    android:layout_marginEnd="2dp"
-                    android:scaleType="centerInside"
-                    android:src="@drawable/ic_ime_switcher_default"
-                    android:visibility="invisible"
-                    android:contentDescription="@string/accessibility_ime_switch_button" />
-            </FrameLayout>
-
-            <!-- Recents always at the far right. -->
-            <com.android.systemui.statusbar.policy.KeyButtonView
-                android:id="@+id/recent_apps"
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_recent"
-                android:scaleType="centerInside"
-                android:layout_weight="0"
-                android:contentDescription="@string/accessibility_recent"
-                />
-        </LinearLayout>
-
-        <!-- lights out layout to match exactly -->
-        <LinearLayout
-            android:layout_height="match_parent"
-            android:layout_width="match_parent"
-            android:orientation="horizontal"
-            android:id="@+id/lights_out"
-            android:visibility="gone"
-            >
-            <ImageView
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_lights_out_dot_small"
-                android:scaleType="center"
-                android:layout_weight="0"
-                />
-            <ImageView
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_lights_out_dot_large"
-                android:scaleType="center"
-                android:layout_weight="0"
-                />
-            <Space
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                />
-            <ImageView
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_lights_out_dot_small"
-                android:scaleType="center"
-                android:layout_weight="0"
-                />
-        </LinearLayout>
-
-        <com.android.systemui.statusbar.policy.DeadZone
-            android:id="@+id/deadzone"
-            android:layout_height="match_parent"
-            android:layout_width="match_parent"
-            systemui:minSize="@dimen/navigation_bar_deadzone_size"
-            systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
-            systemui:holdTime="@integer/navigation_bar_deadzone_hold"
-            systemui:decayTime="@integer/navigation_bar_deadzone_decay"
-            systemui:orientation="horizontal"
-            android:layout_gravity="top"
-            />
-    </FrameLayout>
-
-    <!-- Landscape layout. -->
-    <FrameLayout android:id="@+id/rot90"
-        android:layout_height="match_parent"
-        android:layout_width="match_parent"
-        android:visibility="gone"
-        android:paddingTop="0dp"
-        >
-
-        <LinearLayout
-            android:layout_height="match_parent"
-            android:layout_width="match_parent"
-            android:orientation="horizontal"
-            android:clipChildren="false"
-            android:clipToPadding="false"
-            android:id="@+id/nav_buttons"
-            android:animateLayoutChanges="true"
-            >
-
-            <!-- Back button is flush left. -->
-            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_back"
-                android:scaleType="centerInside"
-                systemui:keyCode="4"
-                android:layout_weight="0"
-                android:contentDescription="@string/accessibility_back"
-                />
-            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
-                android:layout_width="64dp" android:paddingStart="4dp" android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_home"
-                android:scaleType="centerInside"
-                systemui:keyCode="3"
-                systemui:keyRepeat="true"
-                android:layout_weight="0"
-                android:contentDescription="@string/accessibility_home"
-                />
-
-            <!-- Container for the app shelf. -->
-            <LinearLayout
-                android:id="@+id/app_shelf"
-                android:orientation="horizontal"
-                android:layout_height="match_parent"
-                android:layout_width="0dp"
-                android:layout_weight="1"
-                >
-                <com.android.systemui.statusbar.phone.NavigationBarApps
-                    android:id="@+id/navigation_bar_apps"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    />
-            </LinearLayout>
-
-            <FrameLayout
-                android:layout_width="@dimen/navigation_extra_key_width"
-                android:layout_height="match_parent"
-                android:layout_marginEnd="2dp"
-                android:layout_weight="0"
-                android:visibility="gone" >
-                <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
-                    android:layout_width="@dimen/navigation_extra_key_width"
-                    android:layout_height="match_parent"
-                    android:layout_marginEnd="2dp"
-                    android:src="@drawable/ic_sysbar_menu"
-                    android:scaleType="centerInside"
-                    systemui:keyCode="82"
-                    android:visibility="invisible"
-                    android:contentDescription="@string/accessibility_menu" />
-                <com.android.systemui.statusbar.policy.KeyButtonView
-                    android:id="@+id/ime_switcher"
-                    android:layout_width="@dimen/navigation_extra_key_width"
-                    android:layout_height="match_parent"
-                    android:layout_marginEnd="2dp"
-                    android:src="@drawable/ic_ime_switcher_default"
-                    android:visibility="invisible"
-                    android:contentDescription="@string/accessibility_ime_switch_button"
-                    android:scaleType="centerInside" />
-            </FrameLayout>
-
-            <!-- Recents always at the far right. -->
-            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_recent"
-                android:scaleType="centerInside"
-                android:layout_weight="0"
-                android:contentDescription="@string/accessibility_recent"
-                />
-        </LinearLayout>
-
-        <!-- lights out layout to match exactly -->
-        <LinearLayout
-            android:layout_height="match_parent"
-            android:layout_width="match_parent"
-            android:orientation="horizontal"
-            android:id="@+id/lights_out"
-            android:visibility="gone"
-            >
-            <ImageView
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_lights_out_dot_small"
-                android:scaleType="center"
-                android:layout_weight="0"
-                />
-            <ImageView
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_lights_out_dot_large"
-                android:scaleType="center"
-                android:layout_weight="0"
-                />
-            <Space
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                />
-            <ImageView
-                android:layout_width="64dp"
-                android:paddingStart="4dp"
-                android:paddingEnd="4dp"
-                android:layout_height="match_parent"
-                android:src="@drawable/ic_sysbar_lights_out_dot_small"
-                android:scaleType="center"
-                android:layout_weight="0"
-                />
-        </LinearLayout>
-
-        <com.android.systemui.statusbar.policy.DeadZone
-            android:id="@+id/deadzone"
-            android:layout_height="match_parent"
-            android:layout_width="match_parent"
-            systemui:minSize="@dimen/navigation_bar_deadzone_size"
-            systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
-            systemui:holdTime="@integer/navigation_bar_deadzone_hold"
-            systemui:decayTime="@integer/navigation_bar_deadzone_decay"
-            systemui:orientation="horizontal"
-            android:layout_gravity="top"
-            />
-    </FrameLayout>
-</com.android.systemui.statusbar.phone.NavigationBarView>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index 7ebf4ed..f9a3653 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -26,10 +26,9 @@
         android:layout_height="match_parent">
 
         <LinearLayout
-            android:id="@+id/start_group"
+            android:id="@+id/ends_group"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:gravity="start"
             android:orientation="horizontal" />
 
         <LinearLayout
@@ -39,13 +38,6 @@
             android:gravity="center"
             android:orientation="horizontal" />
 
-        <LinearLayout
-            android:id="@+id/end_group"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:gravity="end"
-            android:orientation="horizontal" />
-
     </FrameLayout>
 
     <FrameLayout
@@ -54,10 +46,9 @@
         android:layout_height="match_parent">
 
         <LinearLayout
-            android:id="@+id/start_group_lightsout"
+            android:id="@+id/ends_group_lightsout"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:gravity="start"
             android:orientation="horizontal" />
 
         <LinearLayout
@@ -67,13 +58,6 @@
             android:gravity="center"
             android:orientation="horizontal" />
 
-        <LinearLayout
-            android:id="@+id/end_group_lightsout"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:gravity="end"
-            android:orientation="horizontal" />
-
     </FrameLayout>
 
     <com.android.systemui.statusbar.policy.DeadZone
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 46df973..df32911 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -26,10 +26,9 @@
         android:layout_height="match_parent">
 
         <com.android.systemui.statusbar.phone.ReverseLinearLayout
-            android:id="@+id/start_group"
+            android:id="@+id/ends_group"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:gravity="bottom"
             android:orientation="vertical" />
 
         <com.android.systemui.statusbar.phone.ReverseLinearLayout
@@ -39,13 +38,6 @@
             android:gravity="center"
             android:orientation="vertical" />
 
-        <com.android.systemui.statusbar.phone.ReverseLinearLayout
-            android:id="@+id/end_group"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:gravity="top"
-            android:orientation="vertical" />
-
     </FrameLayout>
 
     <FrameLayout
@@ -54,10 +46,9 @@
         android:layout_height="match_parent">
 
         <com.android.systemui.statusbar.phone.ReverseLinearLayout
-            android:id="@+id/start_group_lightsout"
+            android:id="@+id/ends_group_lightsout"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:gravity="bottom"
             android:orientation="vertical" />
 
         <com.android.systemui.statusbar.phone.ReverseLinearLayout
@@ -67,13 +58,6 @@
             android:gravity="center"
             android:orientation="vertical" />
 
-        <com.android.systemui.statusbar.phone.ReverseLinearLayout
-            android:id="@+id/end_group_lightsout"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:gravity="top"
-            android:orientation="vertical" />
-
     </FrameLayout>
 
     <com.android.systemui.statusbar.policy.DeadZone
diff --git a/packages/SystemUI/res/layout/notification_children_divider.xml b/packages/SystemUI/res/layout/notification_children_divider.xml
index 53273cf..dad7cea 100644
--- a/packages/SystemUI/res/layout/notification_children_divider.xml
+++ b/packages/SystemUI/res/layout/notification_children_divider.xml
@@ -19,5 +19,5 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/notification_more_divider"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/notification_children_divider_height"
+    android:layout_height="@dimen/notification_divider_height"
     android:background="#61000000" />
diff --git a/packages/SystemUI/res/layout/qs_customize_panel.xml b/packages/SystemUI/res/layout/qs_customize_panel.xml
index f430fa5..e56431b 100644
--- a/packages/SystemUI/res/layout/qs_customize_panel.xml
+++ b/packages/SystemUI/res/layout/qs_customize_panel.xml
@@ -87,9 +87,7 @@
             android:id="@+id/quick_settings_panel"
             android:background="#0000"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="@dimen/notification_side_padding"
-            android:layout_marginRight="@dimen/notification_side_padding" />
+            android:layout_height="wrap_content" />
 
     </com.android.systemui.tuner.AutoScrollView>
 
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 2377684..6784695 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -23,8 +23,6 @@
     android:layout_width="@dimen/notification_panel_width"
     android:layout_height="@dimen/status_bar_header_height"
     android:layout_gravity="@integer/notification_panel_layout_gravity"
-    android:paddingStart="@dimen/notification_side_padding"
-    android:paddingEnd="@dimen/notification_side_padding"
     android:clipChildren="false"
     android:clipToPadding="false"
     android:baselineAligned="false"
@@ -70,6 +68,18 @@
 
         </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"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 12cf137..89abe2d 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -55,20 +55,13 @@
                     layout="@layout/qs_panel"
                     android:layout_marginTop="@dimen/status_bar_header_height_expanded"
                     android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginLeft="@dimen/notification_side_padding"
-                    android:layout_marginRight="@dimen/notification_side_padding"/>
+                    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"
-                    android:layout_marginTop="@dimen/notifications_top_padding" />
-
-                <View
-                    android:layout_height="@dimen/notification_side_padding"
                     android:layout_width="match_parent" />
             </LinearLayout>
         </com.android.systemui.statusbar.phone.ObservableScrollView>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 5eca471..dd75dbf 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -23,8 +23,6 @@
     android:layout_width="@dimen/notification_panel_width"
     android:layout_height="@dimen/status_bar_header_height"
     android:layout_gravity="@integer/notification_panel_layout_gravity"
-    android:paddingStart="@dimen/notification_side_padding"
-    android:paddingEnd="@dimen/notification_side_padding"
     android:baselineAligned="false"
     android:elevation="4dp"
     android:background="@drawable/notification_header_bg"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml b/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
deleted file mode 100644
index e220a16..0000000
--- a/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<!-- Extends FrameLayout -->
-<com.android.systemui.statusbar.SpeedBumpView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/speed_bump_height"
-    android:visibility="gone"
-    >
-    <com.android.systemui.statusbar.AlphaOptimizedView
-        android:id="@+id/speedbump_line"
-        android:layout_width="match_parent"
-        android:layout_height="1dp"
-        android:background="#6fdddddd"
-        android:layout_gravity="center_vertical"/>
-</com.android.systemui.statusbar.SpeedBumpView>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 4c80b48..3dca77d 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -65,8 +65,6 @@
                  android:layout_width="@dimen/notification_panel_width"
                  android:layout_height="wrap_content"
                  android:layout_gravity="@integer/notification_panel_layout_gravity"
-                 android:paddingLeft="@dimen/notification_side_padding"
-                 android:paddingRight="@dimen/notification_side_padding"
                  android:visibility="invisible">
         <FrameLayout
                 android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 7cbc55c..34796cd 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -19,8 +19,6 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
-    android:layout_marginLeft="@dimen/notification_side_padding"
-    android:layout_marginRight="@dimen/notification_side_padding"
     android:background="@drawable/volume_dialog_background"
     android:translationZ="4dp" >
 
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index cb68c9d..f1000ff 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume en Moenie steur nie"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"Aktiveer \'moenie steur nie\' met volume af"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"Verlaat \'moenie steur nie\' met volume op"</string>
+    <string name="battery" msgid="7498329822413202973">"Battery"</string>
+    <string name="clock" msgid="7416090374234785905">"Horlosie"</string>
+    <string name="headset" msgid="4534219457597457353">"Kopstuk"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Oorfone is gekoppel"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Kopstuk is gekoppel"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Aktiveer of deaktiveer ikone om op die statusbalk gewys te word."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-af/strings_car.xml b/packages/SystemUI/res/values-af/strings_car.xml
new file mode 100644
index 0000000..7c6f609
--- /dev/null
+++ b/packages/SystemUI/res/values-af/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Ry veilig"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Bly heeltemal bewus van bestuurtoestande en gehoorsaam toepaslike wette altyd. Rigtingaanwysings sal dalk onakkuraat, onvolledig, gevaarlik, ontoepaslik of verbode wees of behels dat administratiewe gebiede oorgesteek word. Besigheidsinligting sal dalk ook onakkuraat of onvolledig wees. Data is nie intyds nie en liggingakkuraatheid kan nie gewaarborg word nie. Moenie jou mobiele toestel hanteer of programme wat nie vir Android Auto bedoel is, gebruik terwyl jy bestuur nie."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4d44de7..fa8dc9d 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ድምጽ እና አትረብሽ"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"ድምጽ ሲቀነስ አትረብሽ አስገባ"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"ድምጽ ሲጨመር አትረብሽን ትተህ ውጣ"</string>
+    <string name="battery" msgid="7498329822413202973">"ባትሪ"</string>
+    <string name="clock" msgid="7416090374234785905">"ሰዓት"</string>
+    <string name="headset" msgid="4534219457597457353">"ጆሮ ማዳመጫ"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"የጆር ማዳመጫዎች ተገናኝተዋል"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"የጆሮ ማዳመጫ ተገናኝቷል"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"አዶዎች በሁኔታ አሞሌ ላይ እንዲታዩ ወይም እንዳይታዩ ያንቁ ወይም ያሰናክሉ።"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings_car.xml b/packages/SystemUI/res/values-am/strings_car.xml
new file mode 100644
index 0000000..8550c42
--- /dev/null
+++ b/packages/SystemUI/res/values-am/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ደህንነትዎን ጠብቀው ያሽከርክሩ"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"የመኪና አነዳድ ሁኔታዎችን በተመለከተ ሙሉ በሙሉ ግንዛቤ ይኑርዎት፣ እንዲሁም የሚመለከታቸውን ሕጎች ሁልጊዜ ያክብሩ። የሚሰጡ አቅጣጫዎች ምናልባት ትክክል ያልሆኑ፣ ያልተሟሉ፣ አደገኛ፣ አግባብ ያልሆኑ፣ የተከለከሉ ወይም አስተዳደራዊ አካባቢዎችን ማቋረጥን የሚያካትቱ ሊሆኑ ይችላሉ። በተጨማሪም የንግድ ሥራ መረጃ ትክክል ያልሆነ ወይም ያልተሟላ ሊሆን ይችላል። ውሂብ ቅጽበታዊ አይደለም፣ እና የአካባቢ ትክክለኛነት ዋስትና ሊሰጥበት አይችልም። መኪና በሚነዱበት ጊዜ የእርስዎን ተንቀሳቃሽ መሣሪያ አይነካኩ ወይም ለAndroid Auto የታለሙ መተግበሪያዎችን አይጠቀሙ።"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index f7128e4..10853bf 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -336,8 +336,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"الأولوية \nفقط"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"التنبيهات\nفقط"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"الكل"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"الكل\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"جارٍ الشحن (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> حتى الامتلاء)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"جارٍ الشحن سريعًا (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> حتى الاكتمال)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"جارٍ الشحن ببطء (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> حتى الاكتمال)"</string>
@@ -487,14 +486,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"الشاشة الرئيسية"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"الأحدث"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"رجوع"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"إظهار خيار \"الرجاء عدم الإزعاج\" في مستوى الصوت"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"السماح بالتحكم الكامل في خيار \"الرجاء عدم الإزعاج\" ضمن مربع حوار مستوى الصوت."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"إعدادات مستوى الصوت و\"الرجاء عدم الإزعاج\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"تشغيل \"الرجاء عدم الإزعاج\" عند خفض مستوى الصوت"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"تعطيل \"الرجاء عدم الإزعاج\" عند رفع مستوى الصوت"</string>
+    <string name="battery" msgid="7498329822413202973">"البطارية"</string>
+    <string name="clock" msgid="7416090374234785905">"ساعة"</string>
+    <string name="headset" msgid="4534219457597457353">"سماعة الرأس"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"تم توصيل سماعات رأس"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"تم توصيل سماعات رأس"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"يمكنك تمكين أو تعطيل الرموز بحيث لا تظهر في شريط الحالة."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings_car.xml b/packages/SystemUI/res/values-ar/strings_car.xml
new file mode 100644
index 0000000..0f315a4
--- /dev/null
+++ b/packages/SystemUI/res/values-ar/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"القيادة بأمان"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏عليك التعرف بشكل تام على ظروف القيادة والالتزام بالقوانين السارية. ويمكن أن تكون الاتجاهات غير دقيقة أو غير مكتملة أو خطيرة أو غير مناسبة أو محظورة أو تتضمن عبور مناطق إدارية. ويمكن أن تكون معلومات الأنشطة التجارية أيضًا غير دقيقة أو غير مكتملة. ولا يتم نشر البيانات في الوقت الفعلي، كما لا يمكن ضمان دقة المواقع. ولا تتعامل مع جهازك الجوّال أو تستخدم تطبيقات ليست متوافقة مع Android Auto أثناء القيادة."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 71ced7c..00b78b2 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Yalnız\nprioritet"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Yalnız\nalarmlar"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Bütün"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Bütün\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Qidalanır (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> dolana kimi)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Sürətli qidalanır (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> dolana kimi)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Ləng qidalanır (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> dolana kimi)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Əsas səhifə"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Sonuncular"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Geri"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Səsdə \"narahat etməyin\" rejimini göstərin"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Səs dioloqunda \"narahat etməyin\" rejiminin tam nərarətinə icazə verin."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Səs və \"narahat etməyin\" rejimi"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Aşağı səsdə \"narahat etməyin\" rejimini daxil edin"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Yuxarı səsdə \"narahat etməyin\" rejimini daxil edin"</string>
+    <string name="battery" msgid="7498329822413202973">"Batareya"</string>
+    <string name="clock" msgid="7416090374234785905">"Saat"</string>
+    <string name="headset" msgid="4534219457597457353">"Qulaqlıq"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Qulaqlıq qoşulub"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Qulaqlıq qoşulub"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"İkonaların status panelində görünməsini aktiv və ya deaktiv edin."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings_car.xml b/packages/SystemUI/res/values-az-rAZ/strings_car.xml
new file mode 100644
index 0000000..9ac7ce0
--- /dev/null
+++ b/packages/SystemUI/res/values-az-rAZ/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Təhlükəsiz sürün"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Yol şəraitindən tam xəbərdar olun və hər zaman tətbiq olunan qaydalara riayət edin. İstiqamətlər qeyri-dəqiq, natamam, təhlükəli, uyğun olmayan, qadağan edilmiş və ya inzibati sahələrə keçid ilə nəticələnə bilər. Biznes məlumatı da qeyri-dəqiq və ya natamam ola bilər. Data real vaxtda deyil və məkan dəqiqliyinə zəmanət verilmir. Avtomobil idarə edərkən mobil cihazınızı elinizə almayın və ya Android Avto üçün nəzərdə tutulmamış tətbiqlərdən istifadə etməyin."</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 fd98abc..4b3f157 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -333,8 +333,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Samo\npriorit. prekidi"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Samo\nalarmi"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Sve"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Svi\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Punjenje (pun je za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Brzo se puni (napuniće se za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sporo se puni (napuniće se za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -484,14 +483,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni sadržaj"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazad"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Prikaži podešavanje Ne uznemiravaj u dijalogu za jačinu zvuka"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Dozvoljava potpunu kontrolu podešavanja Ne uznemiravaj u dijalogu za jačinu zvuka."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Jačina zvuka i Ne uznemiravaj"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Uđi u režim Ne uznemiravaj kada je zvuk utišan"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Izađi iz režima Ne uznemiravaj kada je zvuk pojačan"</string>
+    <string name="battery" msgid="7498329822413202973">"Baterija"</string>
+    <string name="clock" msgid="7416090374234785905">"Sat"</string>
+    <string name="headset" msgid="4534219457597457353">"Naglavne slušalice"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Slušalice su povezane"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Naglavne slušalice su povezane"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Omogućite ili onemogućite prikazivanje ikona na statusnoj traci."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml
new file mode 100644
index 0000000..f45af7c
--- /dev/null
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vozite bezbedno"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uvek vodite računa o uslovima vožnje i uvek poštujte primenjive zakone. Uputstva mogu da budu netačna, nepotpuna, opasna, neprikladna ili zabranjena, odnosno da podrazumevaju prelazak između administrativnih oblasti. I podaci o preduzeću mogu da budu netačni ili nepotpuni. Podaci ne nastaju u realnom vremenu i ne možemo da garantujemo preciznost lokacije. Nemojte da upotrebljavate mobilni uređaj niti da koristite aplikacije koje nisu namenjene za Android Auto tokom vožnje."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index e8f7f23..a5fdd8e 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Само\nс приоритет"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Само\nбудилници"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Всички"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Всички\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Зарежда се (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до пълно зареждане)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Зарежда се бързо (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до пълно зареждане)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Зарежда се бавно (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до пълно зареждане)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Начало"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Скорошни"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Показване на „Не безпокойте“ в прозореца за силата на звука"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Достъп до всички опции за управление на „Не безпокойте“ в диалоговия прозорец за силата на звука."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Сила на звука и „Не безпокойте“"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Вкл. на „Не безпокойте“ при намаляване на силата на звука"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Изкл. на „Не безпокойте“ при увеличаване на силата на звука"</string>
+    <string name="battery" msgid="7498329822413202973">"Батерия"</string>
+    <string name="clock" msgid="7416090374234785905">"Часовник"</string>
+    <string name="headset" msgid="4534219457597457353">"Слушалки"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Слушалките (без микрофон) са свързани"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Слушалките са свързани"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Активиране или деактивиране на показването на икони в лентата на състоянието."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings_car.xml b/packages/SystemUI/res/values-bg/strings_car.xml
new file mode 100644
index 0000000..bd9fe79
--- /dev/null
+++ b/packages/SystemUI/res/values-bg/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Карайте внимателно"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Бъдете осведомени за условията при шофиране и винаги спазвайте приложимите закони. Упътванията може да са неточни, непълни, опасни, неподходящи, забранени или да включват преминаване през административни райони. Бизнес информацията може също да е неточна или непълна. Данните не са в реално време и точността на местоположението не може да се гарантира. Не работете с мобилното си устройство, нито използвайте приложения, които не са предназначени за Android Auto, докато шофирате."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index a49ab40..d6f5868 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"শুধুমাত্র\nঅগ্রাধিকার"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"শুধুমাত্র\nঅ্যালার্মগুলি"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"সমস্ত"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"সমস্ত\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"চার্জ হচ্ছে (পূর্ণ হতে <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> সময় বাকি)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"দ্রুত চার্জ হচ্ছে (পূর্ণ হতে <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> সময় বাকি)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ধীরে ধীরে চার্জ হচ্ছে (পূর্ণ হতে <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> সময় বাকি)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"হোম"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"সাম্প্রতিকগুলি"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"পিছনে"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"ভলিউমে \'বিরক্ত করবেন না\' দেখাবেন না"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"ভলিউম ডায়লগে \"বিরক্ত করবেন না\" এর পূর্ণ নিয়ন্ত্রণের মঞ্জুরি দিন৷"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ভলিউম এবং \'বিরক্ত করবেন না\'"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"ভলিউম কমানোর মাধ্যেমে \'বিরক্ত করবেন না\' চালু করুন"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ভলিউম বাড়ানোর মাধ্যেমে \'বিরক্ত করবেন না\' থেকে প্রস্থান করুন"</string>
+    <string name="battery" msgid="7498329822413202973">"ব্যাটারি"</string>
+    <string name="clock" msgid="7416090374234785905">"ঘড়ি"</string>
+    <string name="headset" msgid="4534219457597457353">"হেডসেট"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"হেডফোনগুলি সংযুক্ত হয়েছে"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"হেডসেট সংযুক্ত হয়েছে"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"স্থিতি দন্ডে দেখানোর জন্য আইকনগুলিকে সক্ষম বা অক্ষম করুন৷"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings_car.xml b/packages/SystemUI/res/values-bn-rBD/strings_car.xml
new file mode 100644
index 0000000..d8a8732
--- /dev/null
+++ b/packages/SystemUI/res/values-bn-rBD/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"সাবধানে চালান"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"গাড়ি চালানোর সময় সর্বদা সতর্ক থাকুন এবং প্রযোজ্য আইন মেনে চলুন৷ দিকনির্দেশ ভুল, অসম্পূর্ণ, বিপজ্জনক, অনুপযুক্ত, নিষিদ্ধ হতে পারে বা প্রশাসনিক এলাকাগুলি অতিক্রম করতে হতে পারে৷ বাণিজ্যিক তথ্য ভুল বা অসম্পূর্ণ হতে পারে৷ ডেটা প্রকৃত সময়ের নয় এবং অবস্থানের নির্ভুলতা নিশ্চিত করাও সম্ভব নয়৷ গাড়ি চালানোর সময় আপনার মোবাইল ডিভাইসটিকে বা Android Auto এর জন্য উপযুক্ত নয় এমন অ্যাপগুলিকে ব্যবহার করবেন না৷"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings_car.xml b/packages/SystemUI/res/values-bs-rBA/strings_car.xml
new file mode 100644
index 0000000..744eea8
--- /dev/null
+++ b/packages/SystemUI/res/values-bs-rBA/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vozite sigurno"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uvijek budite upoznati s uslovima za vožnju i poštujte važeće zakone. Upute za kretanje mogu biti netačne, nepotpune, opasne, neprikladne, zabranjene ili takve da obuhvataju prelaženje preko administrativnih područja. Poslovne informacije takođe mogu biti netačne ili nepotpune. Podaci nisu u realnom vremenu, a tačnost lokacije se ne može garantirati. U vožnji nemojte rukovati mobilnim uređajem ili koristiti aplikacije koje nisu namijenjene za Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 0fce766..714b750 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Només\ninterr. prior."</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Només\nalarmes"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Totes"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Totes\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregant (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar la càrrega)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Càrrega ràpida (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar-se)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Càrrega lenta (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar-se)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inici"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recents"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Enrere"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Mostra el mode No molesteu al volum"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Permet el control complet del mode No molesteu al quadre de diàleg de volum."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volum i mode No molesteu"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Activa el mode No molesteu abaixant el volum"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Desactiva el mode No molesteu apujant el volum"</string>
+    <string name="battery" msgid="7498329822413202973">"Bateria"</string>
+    <string name="clock" msgid="7416090374234785905">"Rellotge"</string>
+    <string name="headset" msgid="4534219457597457353">"Auriculars"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Auriculars connectats"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Auriculars connectats"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Activa o desactiva les icones a la barra d\'estat."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings_car.xml b/packages/SystemUI/res/values-ca/strings_car.xml
new file mode 100644
index 0000000..efcac23
--- /dev/null
+++ b/packages/SystemUI/res/values-ca/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Condueix amb precaució"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Estigues al cas de la conducció i respecta sempre les lleis aplicables. Les indicacions poden ser inexactes, perilloses, inadequades o incompletes, o bé poden comportar maniobres prohibides o que creuis circumscripcions territorials. La informació de les empreses també pot ser inexacta o incompleta. No s\'ofereixen dades en temps real i no es pot garantir la precisió de les ubicacions. Mentre condueixes, no utilitzis el dispositiu mòbil ni cap aplicació que no estigui destinada a Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 6fff76b..dcd42e0 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -334,8 +334,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Pouze\nprioritní"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Pouze\nbudíky"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Vše"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Všechna\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Rychlé nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Pomalé nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -485,14 +484,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Plocha"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Poslední"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Zpět"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Zobrazovat panel Nerušit v dialogu Hlasitost"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Umožňuje povolit úplné ovládání režimu Nerušit v dialogu Hlasitost."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Hlasitost a režim Nerušit"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Při snížení hlasitosti přejít do režimu Nerušit"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Při zvýšení hlasitosti ukončit režim Nerušit"</string>
+    <string name="battery" msgid="7498329822413202973">"Baterie"</string>
+    <string name="clock" msgid="7416090374234785905">"Hodiny"</string>
+    <string name="headset" msgid="4534219457597457353">"Náhlavní souprava"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Sluchátka připojena"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Náhlavní souprava připojena"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Umožňuje aktivovat nebo deaktivovat zobrazení ikon na stavovém řádku."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings_car.xml b/packages/SystemUI/res/values-cs/strings_car.xml
new file mode 100644
index 0000000..d5e3324
--- /dev/null
+++ b/packages/SystemUI/res/values-cs/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Řiďte bezpečně"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Věnujte plnou pozornost řízení a dodržujte platné předpisy. Trasy mohou být nepřesné, neúplné, nebezpečné, nevhodné, zakázané nebo mohou zahrnovat překročení hranic. Informace o firmách mohou být také nepřesné nebo neúplné. Data se neaktualizují v reálném čase a přesnost polohy nelze zaručit. Mobilní zařízení ani aplikace určené pro Android Auto nepoužívejte za jízdy."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 2941927..835ce69 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Kun\nprioritet"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Kun\nalarmer"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Alle\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Oplader (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Hurtig opladning (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Langsom opladning (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Start"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Seneste"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tilbage"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Vis Forstyr ikke i Lydstyrke"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Tillad fuld kontrol over Forstyr ikke i dialogboksen Lydstyrke."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Lydstyrke og Forstyr ikke"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Aktivér Forstyr ikke med Lydstyrke ned"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Afslut Forstyr ikke med Lydstyrke op"</string>
+    <string name="battery" msgid="7498329822413202973">"Batteri"</string>
+    <string name="clock" msgid="7416090374234785905">"Ur"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Hovedtelefoner er tilsluttet"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset er forbundet"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Slå visning af ikoner i statusbjælken til eller fra."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings_car.xml b/packages/SystemUI/res/values-da/strings_car.xml
new file mode 100644
index 0000000..6a421da
--- /dev/null
+++ b/packages/SystemUI/res/values-da/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Kør forsigtigt"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Vær opmærksom på køreforholdene, og overhold altid færdselsloven. Rutevejledningen kan være unøjagtig, ufuldstændig, farlig, upassende, forbudt eller involvere krydsning af forbudte områder. Virksomhedsoplysninger kan også være unøjagtige eller ufuldstændige. Data er ikke i realtid, og placeringers nøjagtighed kan ikke garanteres. Håndter ikke din mobilenhed, og brug ikke apps, der ikke er beregnet til Android Auto, mens du kører."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 9afa618..4888c23 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Nur\nwichtige"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Nur\nWecker"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Alle\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Wird aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Wird schnell aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Wird langsam aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startseite"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Letzte"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Zurück"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"\"Bitte nicht stören\" bei der Lautstärkeregelung anzeigen"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Volle Kontrolle von \"Bitte nicht stören\" im kleinen Fenster zur Lautstärkeregelung erlauben."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Lautstärke und \"Bitte nicht stören\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"\"Bitte nicht stören\" bei \"Leiser\" aktivieren"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"\"Bitte nicht stören\" bei \"Lauter\" deaktivieren"</string>
+    <string name="battery" msgid="7498329822413202973">"Akku"</string>
+    <string name="clock" msgid="7416090374234785905">"Uhr"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Mit Kopfhörer verbunden"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Mit Headset verbunden"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Symbole in der Statusleiste ein- bzw. ausblenden"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings_car.xml b/packages/SystemUI/res/values-de/strings_car.xml
new file mode 100644
index 0000000..5b5920e
--- /dev/null
+++ b/packages/SystemUI/res/values-de/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Sicher fahren"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Achte stets auf die Straßenverhältnisse und halte dich an die geltenden Gesetze. Routen können unter Umständen fehlerhaft, unvollständig, gefährlich, ungeeignet oder verboten sein oder das Überqueren von Verwaltungsgrenzen erfordern. Informationen zum Unternehmen können ebenfalls fehlerhaft oder unvollständig sein. Die Datenübertragung erfolgt nicht in Echtzeit und die Genauigkeit der Standortangaben kann nicht gewährleistet werden. Bediene während der Fahrt nicht dein Mobilgerät und verwende keine Apps, die du nicht über Android Auto steuern kannst."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index f128544..882e5fa 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Μόνο\nπροτεραιότητας"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Μόνο\nειδοποιήσεις"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Όλα"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Όλες\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Φόρτιση (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> για πλήρη φόρτιση)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Γρήγορη φόρτιση (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> για πλήρη φόρτιση)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Αργή φόρτιση (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> για πλήρη φόρτιση)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Αρχική οθόνη"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Πρόσφατα"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Πίσω"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Εμφάνιση λειτουργίας \"Μην ενοχλείτε\" στην ένταση ήχου"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Να επιτρέπεται ο πλήρης έλεγχος της λειτουργίας \"Μην ενοχλείτε\" στο παράθυρο διαλόγου ελέγχου έντασης."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Ένταση ήχου και λειτουργία \"Μην ενοχλείτε\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Ενεργοποίηση λειτουργίας \"Μην ενοχλείτε\" κατά τη μείωση της έντασης ήχου"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Απενεργοποίηση λειτουργίας \"Μην ενοχλείτε\" κατά την αύξηση της έντασης ήχου"</string>
+    <string name="battery" msgid="7498329822413202973">"Μπαταρία"</string>
+    <string name="clock" msgid="7416090374234785905">"Ρολόι"</string>
+    <string name="headset" msgid="4534219457597457353">"Ακουστικά"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Τα ακουστικά συνδέθηκαν"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Τα ακουστικά συνδέθηκαν"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Ενεργοποίηση ή απενεργοποίηση εμφάνιση εικονιδίων στη γραμμή κατάστασης."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings_car.xml b/packages/SystemUI/res/values-el/strings_car.xml
new file mode 100644
index 0000000..e960713
--- /dev/null
+++ b/packages/SystemUI/res/values-el/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Οδηγείτε προσεκτικά"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Μείνετε πλήρως ενημερωμένοι για τις προϋποθέσεις οδήγησης και υπακούτε πάντα τους ισχύοντες νόμους. Οι οδηγίες μπορεί να είναι ανακριβείς, ελλιπείς, επικίνδυνες, ακατάλληλες, απαγορευμένες ή να ανήκουν σε άλλες διοικητικές περιοχές. Οι πληροφορίες επιχειρήσεων μπορεί επίσης να είναι ανακριβείς ή ελλιπείς. Τα δεδομένα δεν είναι σε πραγματικό χρόνο και η ακρίβεια των τοποθεσιών δεν είναι εγγυημένη. Μη χειρίζεστε την κινητή συσκευή σας και μη χρησιμοποιείτε εφαρμογές που δεν προορίζονται για το Android Auto ενώ οδηγείτε."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 38f3d38..6ded945 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume and Do Not Disturb"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"Enter Do Not Disturb on volume down"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"Exit Do Not Disturb on volume up"</string>
+    <string name="battery" msgid="7498329822413202973">"Battery"</string>
+    <string name="clock" msgid="7416090374234785905">"Clock"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Headphones connected"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset connected"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Enable or disable icons from being shown in the status bar."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings_car.xml b/packages/SystemUI/res/values-en-rAU/strings_car.xml
new file mode 100644
index 0000000..81089ba
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rAU/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drive safely"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Stay fully aware of driving conditions and always obey applicable laws. Directions may be inaccurate, incomplete, dangerous, not suitable, prohibited or involve crossing administrative areas. Business information may also be inaccurate or incomplete. Data is not real time and location accuracy cannot be guaranteed. Do not handle your mobile device or use apps not intended for Android Auto while driving."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 38f3d38..6ded945 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume and Do Not Disturb"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"Enter Do Not Disturb on volume down"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"Exit Do Not Disturb on volume up"</string>
+    <string name="battery" msgid="7498329822413202973">"Battery"</string>
+    <string name="clock" msgid="7416090374234785905">"Clock"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Headphones connected"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset connected"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Enable or disable icons from being shown in the status bar."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings_car.xml b/packages/SystemUI/res/values-en-rGB/strings_car.xml
new file mode 100644
index 0000000..81089ba
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rGB/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drive safely"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Stay fully aware of driving conditions and always obey applicable laws. Directions may be inaccurate, incomplete, dangerous, not suitable, prohibited or involve crossing administrative areas. Business information may also be inaccurate or incomplete. Data is not real time and location accuracy cannot be guaranteed. Do not handle your mobile device or use apps not intended for Android Auto while driving."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 38f3d38..6ded945 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume and Do Not Disturb"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"Enter Do Not Disturb on volume down"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"Exit Do Not Disturb on volume up"</string>
+    <string name="battery" msgid="7498329822413202973">"Battery"</string>
+    <string name="clock" msgid="7416090374234785905">"Clock"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Headphones connected"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset connected"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Enable or disable icons from being shown in the status bar."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings_car.xml b/packages/SystemUI/res/values-en-rIN/strings_car.xml
new file mode 100644
index 0000000..81089ba
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rIN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drive safely"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Stay fully aware of driving conditions and always obey applicable laws. Directions may be inaccurate, incomplete, dangerous, not suitable, prohibited or involve crossing administrative areas. Business information may also be inaccurate or incomplete. Data is not real time and location accuracy cannot be guaranteed. Do not handle your mobile device or use apps not intended for Android Auto while driving."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c521912..0cdb4c6 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Solo\nprioridad"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Solo\nalarmas"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Todo"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Todo\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (faltan <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Carga rápida (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar la carga)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Carga lenta (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar la carga)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pantalla principal"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atrás"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Mostrar el panel de control de No interrumpir en el volumen"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Permitir el control total del modo No interrumpir en el cuadro de diálogo de volumen."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volumen y No interrumpir"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Activar el modo No interrumpir al bajar el volumen"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Desactivar el modo No interrumpir al subir el volumen"</string>
+    <string name="battery" msgid="7498329822413202973">"Batería"</string>
+    <string name="clock" msgid="7416090374234785905">"Reloj"</string>
+    <string name="headset" msgid="4534219457597457353">"Auriculares"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Auriculares conectados"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Auriculares conectados"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Habilitar o inhabilitar la visualización de los íconos en la barra de estado"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings_car.xml b/packages/SystemUI/res/values-es-rUS/strings_car.xml
new file mode 100644
index 0000000..647236a
--- /dev/null
+++ b/packages/SystemUI/res/values-es-rUS/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conducir de forma segura"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Permanece atento a la situación de conducción y cumple siempre con las leyes vigentes. Es posible que las indicaciones sean imprecisas, inadecuadas o peligrosas, que estén incompletas, que sugieran maniobras prohibidas o que impliquen atravesar áreas administrativas. La información de las empresas también puede ser imprecisa o estar incompleta. Los datos no se proporcionan en tiempo real ni se puede garantizar la precisión de las ubicaciones. No uses tu dispositivo móvil ni apps no diseñadas para Android Auto mientras conduces."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 8d98049..cd5c95a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volumen y No molestar"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"Activar No molestar al bajar el volumen"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"Salir de No molestar al subir el volumen"</string>
+    <string name="battery" msgid="7498329822413202973">"Batería"</string>
+    <string name="clock" msgid="7416090374234785905">"Reloj"</string>
+    <string name="headset" msgid="4534219457597457353">"Auriculares"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Auriculares conectados"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Auriculares conectados"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Permite mostrar u ocultar iconos en la barra de estado"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings_car.xml b/packages/SystemUI/res/values-es/strings_car.xml
new file mode 100644
index 0000000..e19ca78
--- /dev/null
+++ b/packages/SystemUI/res/values-es/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduce de forma segura"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Permanece atento a la conducción y respeta siempre las normas de tráfico. Las indicaciones pueden ser inexactas, incompletas, peligrosas o inadecuadas o dar lugar a maniobras prohibidas o al cruce de zonas regionales diferentes. La información sobre empresas también puede ser inexacta o estar incompleta. No se ofrecen datos en tiempo real ni se puede garantizar la exactitud de las ubicaciones. No utilices el dispositivo móvil ni aplicaciones que no estén destinadas a Android Auto mientras conduces."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 126bc12..52fc39e 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Helitugevus ja funktsioon Mitte segada"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"Lülita helitugevuse vähendamisel sisse funkt. Mitte segada"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"Lülita helitugevuse suurendamisel välja funkt. Mitte segada"</string>
+    <string name="battery" msgid="7498329822413202973">"Aku"</string>
+    <string name="clock" msgid="7416090374234785905">"Kell"</string>
+    <string name="headset" msgid="4534219457597457353">"Peakomplekt"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Kõrvaklapid on ühendatud"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Peakomplekt on ühendatud"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Lubatakse või keelatakse ikoonide kuvamine olekuribal."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings_car.xml b/packages/SystemUI/res/values-et-rEE/strings_car.xml
new file mode 100644
index 0000000..c41385a
--- /dev/null
+++ b/packages/SystemUI/res/values-et-rEE/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Sõitke turvaliselt"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Olge teadlik sõidutingimustest ja järgige alati kohaldatavaid seadusi. Juhised võivad olla ebatäpsed, mittetäielikud, ohtlikud, sobimatud, keelatud või hõlmata kattuvaid administratiivpiirkondi. Ka ettevõtteteave võib olla ebatäpne või mittetäielik. Andmed pole reaalajas ja asukoha täpsust ei saa garanteerida. Ärge kasutage auto juhtimisel mobiilseadet ega rakendusi, mis pole mõeldud teenuse Android Auto jaoks."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 54154ea..06a43f6 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Lehentasunezkoak\nsoilik"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmak\nsoilik"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Guztiak"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Guztiak\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Bizkor kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mantso kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Hasierako pantaila"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Azkenak"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atzera"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Erakutsi \"Ez molestatu\" aukera bolumenaren leihoan"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Baimendu bolumenaren leihoan \"Ez molestatu\" aukera guztiz kontrolatzea."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Bolumena eta \"Ez molestatu\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Sartu \"Ez molestatu\" egoeran bolumena jaistean"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Irten \"Ez molestatu\" egoeratik bolumena igotzean"</string>
+    <string name="battery" msgid="7498329822413202973">"Bateria"</string>
+    <string name="clock" msgid="7416090374234785905">"Erlojua"</string>
+    <string name="headset" msgid="4534219457597457353">"Mikrofonodun entzungailua"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Aurikularrak konektatu dira"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Mikrofonodun entzungailua konektatu da"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Gaitu edo desgaitu ikonoak egoera-barran erakusteko aukera."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings_car.xml b/packages/SystemUI/res/values-eu-rES/strings_car.xml
new file mode 100644
index 0000000..c4371f7
--- /dev/null
+++ b/packages/SystemUI/res/values-eu-rES/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Gidatu zentzuz"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Egon erne errepidera begira eta gorde lege aplikagarri oro. Agian jarraibideak ez dira guztiz zehatzak, osatuak edo egokiak izango; arriskutsuak izan daitezke edo debekatuta dagoen zerbait egitea edo mugak zeharkatzea proposa diezazukete. Baliteke enpresei buruzko informazioa ere guztiz zehatza edo osatua ez izatea. Datuak ez dira une-unekoak eta ezin da bermatu kokapenaren zehaztasuna. Gidatu bitartean, ez erabili gailu mugikorrik edo Android Auto zerbitzuarekin erabiltzeko egina ez dagoen aplikaziorik."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index da13225..0af19ba 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"فقط\nاولویت‌دار"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"فقط\nهشدارها"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"همه"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"همه\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"در حال شارژ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> تا شارژ کامل)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"در حال شارژ سریع (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> تا شارژ کامل)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"در حال شارژ آهسته (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> تا شارژ کامل)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"صفحه اصلی"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"موارد اخیر"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"برگشت"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"نمایش «مزاحم نشوید» در میزان صدا"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"به حالت «مزاحم نشوید» اجازه داده می‌شود در کادر گفتگوی میزان صدا کنترل کامل داشته باشد."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"میزان صدا و «مزاحم نشوید»"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"وارد شدن به حالت «مزاحم نشوید» در میزان صدای پایین"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"خارج شدن از حالت «مزاحم نشوید» در میزان صدای بالا"</string>
+    <string name="battery" msgid="7498329822413202973">"باتری"</string>
+    <string name="clock" msgid="7416090374234785905">"ساعت"</string>
+    <string name="headset" msgid="4534219457597457353">"هدست"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"هدفون وصل شد"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"هدست وصل شد"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"فعال یا غیرفعال کردن نمایش نمادها در نوار وضعیت."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings_car.xml b/packages/SystemUI/res/values-fa/strings_car.xml
new file mode 100644
index 0000000..e8433fa
--- /dev/null
+++ b/packages/SystemUI/res/values-fa/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"با ایمنی برانید"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏کاملاً از شرایط رانندگی آگاه باشید و همیشه قوانین مربوطه را رعایت کنید. مسیرها ممکن است غیردقیق، ناقص، ناکامل، خطرناک، نامناسب، ممنوع یا مستلزم عبور از تقسیمات کشوری باشند. اطلاعات کسب و کار نیز ممکن است غیردقیق یا ناکامل باشند. داده‌ها بی‌درنگ نیستند و دقت مکان نمی‌تواند تضمین شود. هنگام رانندگی دستگاه همراه را در دست نگیرید یا از برنامه‌هایی که ویژه Android Auto نیستند استفاده نکنید."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 8e89737..327e1df 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Vain\ntärkeät"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Vain\nherätykset"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Kaikki"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Kaikki\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Ladataan (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kunnes täynnä)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Nopea lataus (latausaikaa jäljellä <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Hidas lataus (latausaikaa jäljellä <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Aloitusnäyttö"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Viimeaikaiset"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Takaisin"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Näytä Älä häiritse ‑valinnat äänenvoimakkuudessa"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Näytä kaikki Älä häiritse ‑tilan säädöt äänenvoimakkuusvalinnassa."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Äänenvoimakkuus ja Älä häiritse ‑tila"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Siirry Älä häiritse -tilaan, kun äänenvoimakkuutta lasketaan"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Poistu Älä häiritse -tilasta, kun äänenvoimakkuus nousee"</string>
+    <string name="battery" msgid="7498329822413202973">"Akku"</string>
+    <string name="clock" msgid="7416090374234785905">"Kello"</string>
+    <string name="headset" msgid="4534219457597457353">"Kuulokemikrofoni"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Kuulokkeet liitetty"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Kuulokemikrofoni liitetty"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Ota tilapalkin kuvakkeet käyttöön tai poista ne käytöstä."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings_car.xml b/packages/SystemUI/res/values-fi/strings_car.xml
new file mode 100644
index 0000000..fc94b90
--- /dev/null
+++ b/packages/SystemUI/res/values-fi/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Aja varovasti"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tarkkaile huolellisesti ajo-olosuhteita ja noudata aina voimassa olevia lakeja. Reittiohjeet saattavat olla epätarkkoja, epätäydellisiä, vaarallisia, epäsopivia, kiellettyjä tai kulkea hallintoalueiden läpi. Myös yritystiedot voivat olla epätarkkoja tai epätäydellisiä. Tietoja ei päivitetä reaaliajassa eikä sijaintien tarkkuutta taata. Älä käytä ajon aikana mobiililaitettasi tai sovelluksia, joita ei ole suunniteltu Android Autolle."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index b61a260..7ebb5ab 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priorités\nuniquement"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmes\nuniquement"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Tous"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Tous\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours... (chargée à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charge rapide en cours... (chargé dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charge lente en cours... (chargé dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Précédent"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Fonctionnalité Ne pas déranger dans boîte de dialogue volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Autoriser le contrôle de la fonctionnalité Ne pas déranger dans la boîte de dialogue de modification du volume"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume et fonctionnalité Ne pas déranger"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Activer fonctionnalité Ne pas déranger avec bouton Volume -"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Désactiver fonctionnalité Ne pas déranger avec bouton Volume +"</string>
+    <string name="battery" msgid="7498329822413202973">"Pile"</string>
+    <string name="clock" msgid="7416090374234785905">"Horloge"</string>
+    <string name="headset" msgid="4534219457597457353">"Écouteurs"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Écouteurs connectés"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Écouteurs connectés"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Activer ou désactiver l\'affichage des icônes dans la barre d\'état"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_car.xml b/packages/SystemUI/res/values-fr-rCA/strings_car.xml
new file mode 100644
index 0000000..209773b
--- /dev/null
+++ b/packages/SystemUI/res/values-fr-rCA/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduire en toute sécurité"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tenez compte des conditions de la route et respectez toujours les lois en vigueur. Les itinéraires peuvent être incorrects, incomplets, dangereux, inappropriés ou interdits, et ils peuvent traverser des zones administratives. Les renseignements sur les entreprises peuvent également être incorrects ou incomplets. Les données ne sont pas fournies en temps réel, et la précision de la localisation n\'est pas garantie. Ne manipulez pas votre appareil mobile et n\'utilisez pas d\'applications non conçues pour Android Auto lorsque vous conduisez."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 3d02297..d16f680 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priorité\nuniquement"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmes\nuniquement"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Toujours"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Toutes\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charge rapide… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charge lente… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Précédent"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Fonctionnalité Ne pas déranger dans boîte de dialogue volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Autoriser le contrôle de la fonctionnalité Ne pas déranger dans la boîte de dialogue de modification du volume"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume et fonctionnalité Ne pas déranger"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Activer fonctionnalité Ne pas déranger via le bouton Volume -"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Désactiver fonctionnalité Ne pas déranger via bouton Volume +"</string>
+    <string name="battery" msgid="7498329822413202973">"Batterie"</string>
+    <string name="clock" msgid="7416090374234785905">"Horloge"</string>
+    <string name="headset" msgid="4534219457597457353">"Casque"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Casque connecté"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Casque connecté"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Activer ou désactiver l\'affichage des icônes dans la barre d\'état"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings_car.xml b/packages/SystemUI/res/values-fr/strings_car.xml
new file mode 100644
index 0000000..d42586e
--- /dev/null
+++ b/packages/SystemUI/res/values-fr/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Soyez prudent sur la route"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tenez compte des conditions de conduite et respectez toujours les lois en vigueur. Les itinéraires peuvent être incorrects, incomplets, dangereux, inappropriés ou interdits, et traverser des frontières administratives. Les informations sur les établissements peuvent également être incorrectes ou incomplètes. Les données ne sont pas fournies en temps réel, et la précision de la localisation n\'est pas garantie. Ne manipulez pas votre appareil mobile et n\'utilisez pas d\'applications non conçues pour Android Auto lorsque vous conduisez."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index b69219b..fad6b43 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Só\nprioridade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Só\nalarmas"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Todas"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Todas\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para finalizar a carga)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Cargando rápido (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para rematar a carga)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Cargando lento (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para rematar a carga)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Volver"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Mostrar o modo Non molestar no cadro de diálogo de volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Permite o control completo do modo Non molestar no cadro de diálogo de volume."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume e modo Non molestar"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Activar o modo Non molestar ao baixar o volume"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Desactivar o modo Non molestar ao subir o volume"</string>
+    <string name="battery" msgid="7498329822413202973">"Batería"</string>
+    <string name="clock" msgid="7416090374234785905">"Reloxo"</string>
+    <string name="headset" msgid="4534219457597457353">"Auriculares"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Conectáronse os auriculares"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Conectáronse os auriculares"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Activa ou desactiva a visualización das iconas na barra de estado."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings_car.xml b/packages/SystemUI/res/values-gl-rES/strings_car.xml
new file mode 100644
index 0000000..bb3f8eb
--- /dev/null
+++ b/packages/SystemUI/res/values-gl-rES/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduce de forma segura"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Ten moi en conta as condicións de condución e respecta sempre as leis aplicables. É posible que as indicacións sexan imprecisas, incompletas, perigosas, inadecuadas, estean prohibidas ou que impliquen atravesar áreas administrativas. A información das empresas tamén pode ser imprecisa ou estar incompleta. Os datos non se proporcionan en tempo real e non se garante a precisión da localización. Non manipules o teu dispositivo móbil nin utilices aplicacións que non estean deseñadas para Android Auto mentres conduces."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 1211e7b..576c332 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ફક્ત\nપ્રાધાન્યતા"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ફક્ત\nએલાર્મ્સ"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"તમામ"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"બધી\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ચાર્જ થઈ રહ્યું છે (પૂર્ણ થવામાં <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> બાકી)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ઝડપથી ચાર્જિંગ થઇ રહી છે (પૂર્ણ થવામાં <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> બાકી)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ધીમેથી ચાર્જિંગ થઇ રહી છે (પૂર્ણ થવામાં <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> બાકી)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"હોમ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"તાજેતરના"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"પાછળ"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"વૉલ્યૂમમાં ખલેલ પાડશો નહીં બતાવો"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"વૉલ્યૂમ સંવાદમાં ખલેલ પાડશો નહીંના સંપૂર્ણ નિયંત્રણની મંજૂરી આપો."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"વૉલ્યૂમ અને ખલેલ પાડશો નહીં"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"વૉલ્યૂમ ઘટાડવા પર ખલેલ પાડશો નહીંમાં દાખલ થાઓ"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"વૉલ્યૂમ વધારવા પર ખલેલ પાડશો નહીંમાંથી બહાર નિકળો"</string>
+    <string name="battery" msgid="7498329822413202973">"બૅટરી"</string>
+    <string name="clock" msgid="7416090374234785905">"ઘડિયાળ"</string>
+    <string name="headset" msgid="4534219457597457353">"હેડસેટ"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"હેડફોન કનેક્ટ કર્યાં"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"હેડસેટ કનેક્ટ કર્યો"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"સ્થિતિ બારમાં બતાવવામાં આવતા આઇકન્સને સક્ષમ અથવા અક્ષમ કરો."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings_car.xml b/packages/SystemUI/res/values-gu-rIN/strings_car.xml
new file mode 100644
index 0000000..b22b688
--- /dev/null
+++ b/packages/SystemUI/res/values-gu-rIN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"સુરક્ષિત રીતે વાહન ચલાવો"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ડ્રાઇવિંગ સ્થિતિઓથી સંપૂર્ણપણે વાકેફ રહો અને હંમેશા લાગુ કાયદાઓનું પાલન કરો. દિશા નિર્દેશો અચોક્કસ, અપૂર્ણ, જોખમમકારક, બિન અનુકૂળ, પ્રતિબંધિત અથવા વહીવટી વિસ્તારોને ઓળંગવાનું સમાવતા હોઇ શકે છે. વ્યવસાય માહિતી પણ અચોક્કસ અથવા અપૂર્ણ હોઇ શકે છે. ડેટા રિઅલ-ટાઇમ નથી અને સ્થાન ચોકસાઈની ગેરંટી આપી શકતાં નથી. ડ્રાઇવિંગ કરતી વખતે Android Auto માટે તમારું મોબાઇલ સાધન હેન્ડલ કરવું અથવા ઍપ્લિકેશનનો ઉપયોગ કરવાનું કોઇ પ્રયોજન નથી."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 7e70dee..5d97aa6 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"वॉल्यूम और परेशान न करें"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"वॉल्यूम कम करें पर परेशान न करें डालें"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"वॉल्यूम बढ़ाएं पर परेशान न करें से बाहर निकलें"</string>
+    <string name="battery" msgid="7498329822413202973">"बैटरी"</string>
+    <string name="clock" msgid="7416090374234785905">"घड़ी"</string>
+    <string name="headset" msgid="4534219457597457353">"हैडसेट"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"हेडफ़ोन कनेक्‍ट किए गए"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"हैडसेट कनेक्‍ट किया गया"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"आइकन को स्‍थिति बार में दिखाए जाने से सक्षम या अक्षम करें."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings_car.xml b/packages/SystemUI/res/values-hi/strings_car.xml
new file mode 100644
index 0000000..a643bd8
--- /dev/null
+++ b/packages/SystemUI/res/values-hi/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"सुरक्षित ढंग से गाड़ी चलाएं"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"गाड़ी चलाने की स्थितियों के प्रति पूरी तरह से सतर्क रहें और हमेशा लागू कानूनों का पालन करें. दिशाएं गलत, अपूर्ण, खतरनाक, निषिद्ध हो सकती हैं या उनमें प्रशासनिक क्षेत्रों को पार करना शामिल हो सकता है. व्यावसायिक जानकारी भी गलत या अपूर्ण हो सकती है. डेटा रीयल-टाइम नहीं है और स्थान सटीकता की गारंटी नहीं दी जा सकती. गाड़ी चलाते समय अपने मोबाइल डिवाइस या फ़ोन या Android Auto के लिए अभिप्रेत न किए गए ऐप्स का उपयोग ना करें."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 23cb96b..d96c308 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -333,8 +333,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Samo\nprioritetno"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Samo\nalarmi"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Sve"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Svi\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Brzo punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sporo punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
@@ -484,14 +483,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni zaslon"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Najnovije"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Natrag"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Prikaži \"Ne uznemiravaj\" u glasnoći"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Dopušta potpunu kontrolu nad načinom \"Ne uznemiravaj\" u dijaloškom okviru glasnoće."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Glasnoća i Ne uznemiravaj"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Pokreni \"Ne uznemiravaj\" kada je zvuk stišan"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Zaustavi \"Ne uznemiravaj\" kada je zvuk pojačan"</string>
+    <string name="battery" msgid="7498329822413202973">"Baterija"</string>
+    <string name="clock" msgid="7416090374234785905">"Sat"</string>
+    <string name="headset" msgid="4534219457597457353">"Slušalice"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Slušalice su povezane"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Slušalice su povezane"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Omogućuje ili onemogućuje prikazivanje ikona na traci statusa."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings_car.xml b/packages/SystemUI/res/values-hr/strings_car.xml
new file mode 100644
index 0000000..034bd71d
--- /dev/null
+++ b/packages/SystemUI/res/values-hr/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vozite sigurno"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Pažljivo pratite promet i uvijek se pridržavajte primjenjivih zakona. Upute mogu biti neprecizne, nepotpune, opasne, neprikladne, zabranjene ili mogu uključivati prelazak administrativnih granica. Podaci o tvrtkama također mogu biti neprecizni i nepotpuni. Podaci nisu u stvarnom vremenu i preciznost lokacije nije zajamčena. Tijekom vožnje ne rukujte mobilnim uređajem i ne upotrebljavajte aplikacije koje nisu namijenjene za Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 84454f6..0f4c31b 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Hangvezérlő és „Ne zavarjanak” funkció"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"„Ne zavarjanak” aktiválása hangerőcsökkentéskor"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"„Ne zavarjanak” deaktiválása hangerőnöveléskor"</string>
+    <string name="battery" msgid="7498329822413202973">"Akkumulátor"</string>
+    <string name="clock" msgid="7416090374234785905">"Óra"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Fejhallgató csatlakoztatva"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset csatlakoztatva"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Ikonok megjelenítése és elrejtése az állapotsoron."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings_car.xml b/packages/SystemUI/res/values-hu/strings_car.xml
new file mode 100644
index 0000000..688d88b
--- /dev/null
+++ b/packages/SystemUI/res/values-hu/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vezessen óvatosan"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mindig legyen teljes mértékben tisztában a vezetési körülményekkel, és a vonatkozó törvényeket tartsa be! Az útvonaltervek pontatlanok, hiányosak, veszélyesek, nem megfelelők vagy tiltottak lehetnek, illetve a közforgalom számára nem használható utakat érinthetnek. Az üzleti információk is pontatlanok vagy hiányosak lehetnek. Az adatok nem valós idejűek, ezért nem garantálhatjuk a helyadatok pontosságát. Vezetés közben ne kezelje mobileszközét, illetve ne használjon olyan alkalmazásokat az Android Auto rendszerrel, amelyeket nem ahhoz terveztek."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 89045e1..d135933 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Միայն\nկարևորները"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Միայն\nզարթուցիչ"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Բոլորը"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Բոլորը\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Լիցքավորում (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> մինչև լրիվ լիցքավորումը)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Արագ լիցքավորում (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>՝ մինչև ավարտ)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Դանդաղ լիցքավորում (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>՝ մինչև ավարտ)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Գլխավոր էջ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Վերջինները"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Հետ"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Ցույց տալ Չխանգարել գործառույթը ձայնի կառավարման պատուհանում"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Թույլատրել Չխանգարել գործառույթի ամբողջական վերահսկումը ձայնի կառավարման պատուհանում:"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Ձայնի ուժգնություն և Չխանգարել գործառույթ"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Մտնել Չխանգարել գործառույթ ձայնի նվազեցման կոճակը սեղմելիս"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Ելնել Չխանգարել գործառույթից ձայնի ավելացման կոճակը սեղմելիս"</string>
+    <string name="battery" msgid="7498329822413202973">"Մարտկոց"</string>
+    <string name="clock" msgid="7416090374234785905">"Ժամացույց"</string>
+    <string name="headset" msgid="4534219457597457353">"Ականջակալ"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Ականջակալը կապակցված է"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Ականջակալը կապակցված է"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Միացնել կամ անջատել պատկերակների ցուցադրումը կարգավիճակի գոտում:"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings_car.xml b/packages/SystemUI/res/values-hy-rAM/strings_car.xml
new file mode 100644
index 0000000..4f214f7
--- /dev/null
+++ b/packages/SystemUI/res/values-hy-rAM/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Վարեք ապահով"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Երթևեկության պայմաններին միշտ լավատեղյակ եղեք և կատարեք համապատասխան օրենքների պահանջները: Երթուղիները կարող են լինել սխալ, կիսատ, վտանգավոր, ոչ պատշաճ, արգելված կամ կարող են անցնել վարչական միավորների միջով: Բիզնես տվյալները նույնպես կարող են լինել սխալ կամ կիսատ: Տվյալներն իրական ժամանակում չեն թարմացվում, իսկ տեղադրության ճշգրտությունը չի կարող երաշխավորվել: Մեքենա վարելիս մի օգտագործեք ձեր շարժական սարքը, ինչպես նաև Android Auto-ի համար չնախատեսված հավելվածները:"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index b7ac86d..6335c5d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Hanya\nprioritas"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Hanya\nalarm"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Semua"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Semua\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Mengisi daya (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Mengisi daya dengan cepat (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mengisi daya dengan lambat (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Layar Utama"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaru"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Kembali"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Tampilkan mode jangan ganggu di volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Izinkan kontrol penuh dari mode jangan mengganggu di dialog volume."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume dan mode Jangan ganggu"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Masukkan mode jangan ganggu di tombol kecilkan volume"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Keluar dari mode jangan ganggu di tombol keraskan volume"</string>
+    <string name="battery" msgid="7498329822413202973">"Baterai"</string>
+    <string name="clock" msgid="7416090374234785905">"Jam"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Headphone terhubung"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset terhubung"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Aktifkan atau nonaktifkan ikon yang ditampilkan di bilah status."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings_car.xml b/packages/SystemUI/res/values-in/strings_car.xml
new file mode 100644
index 0000000..cc23ecf
--- /dev/null
+++ b/packages/SystemUI/res/values-in/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Hati-hati saat berkendara"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Tetap perhatikan keadaan saat mengemudi dan selalu patuhi peraturan yang berlaku. Petunjuk arah mungkin tidak akurat, tidak lengkap, berbahaya, tidak cocok, terlarang, atau dapat melewati wilayah administratif. Informasi bisnis juga mungkin tidak akurat atau tidak lengkap. Data tidak dalam waktu nyata dan keakuratan lokasi tidak dijamin. Jangan menggunakan perangkat seluler atau aplikasi yang tidak berkaitan dengan Android Auto saat mengemudi."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index cb2a3bd..76f5389 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Aðeins\nforgangur"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Aðeins\nvekjarar"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Allar"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Allar\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Í hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Í hraðri hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Í hægri hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Heim"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nýlegt"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Til baka"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Sýna „Ónáðið ekki“ í hljóðstyrksvali"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Leyfa fulla stjórn á stillingunni „Ónáðið ekki“ í hljóðstyrksglugganum."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Hljóðstyrkur og „Ónáðið ekki“"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Kveikja á „Ónáðið ekki“ með því að lækka"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Slökkva á „Ónáðið ekki“ með því að hækka"</string>
+    <string name="battery" msgid="7498329822413202973">"Rafhlaða"</string>
+    <string name="clock" msgid="7416090374234785905">"Klukka"</string>
+    <string name="headset" msgid="4534219457597457353">"Höfuðtól"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Heyrnartól tengd"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Höfuðtól tengt"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Birtu eða feldu myndtákn í stöðustikunni."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings_car.xml b/packages/SystemUI/res/values-is-rIS/strings_car.xml
new file mode 100644
index 0000000..65117be
--- /dev/null
+++ b/packages/SystemUI/res/values-is-rIS/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Aktu varlega"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Vertu vakandi fyrir akstursskilyrðum hverju sinni og farðu ævinlega eftir gildandi lögum. Leiðarlýsing kann að vera ónákvæm, ófullkomin, ekki við hæfi, bönnuð eða fela í sér ferðir um opinber svæði. Upplýsingar um fyrirtæki kunna einnig að vera ónákvæmar eða ófullkomnar. Gögn eru ekki í rauntíma og ekki er hægt að tryggja nákvæmni staðsetningarupplýsinga. Ekki handleika fartækið þitt meðan á akstri stendur eða nota forrit sem ekki eru hugsuð fyrir Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 998230d..cfcd42c 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Solo con\npriorità"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Solo\nsveglie"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Tutte"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Tutte\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"In carica (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Ricarica veloce (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Ricarica lenta (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recenti"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Indietro"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Mostra Non disturbare nella finestra del volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Consenti il controllo totale della funzione Non disturbare nella finestra di dialogo del volume."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume e Non disturbare"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Attiva Non disturbare all\'abbassamento del volume"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Disattiva Non disturbare all\'aumento del volume"</string>
+    <string name="battery" msgid="7498329822413202973">"Batteria"</string>
+    <string name="clock" msgid="7416090374234785905">"Orologio"</string>
+    <string name="headset" msgid="4534219457597457353">"Auricolare"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Cuffie collegate"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Auricolare collegato"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Consente di attivare o disattivare la visualizzazione delle icone nella barra di stato."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings_car.xml b/packages/SystemUI/res/values-it/strings_car.xml
new file mode 100644
index 0000000..ae26c9e
--- /dev/null
+++ b/packages/SystemUI/res/values-it/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Guida in modo sicuro"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"È necessario essere sempre pienamente coscienti delle condizioni di guida e rispettare le leggi vigenti. Le indicazioni stradali potrebbero essere imprecise, incomplete, pericolose, non adatte, vietate o implicare l\'attraversamento di confini. Anche le informazioni sulle attività commerciali potrebbero essere imprecise o incomplete. I dati non vengono forniti in tempo reale e non è possibile garantire la precisione della geolocalizzazione. Non maneggiare il dispositivo mobile e non utilizzare app non progettate per Android Auto durante la guida."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index af5edb4..6fd3456 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -334,8 +334,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"התראות בעדיפות\nבלבד"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"התראות\nבלבד"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"הכל"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"הכל\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"טוען (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> עד לסיום)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"בטעינה מהירה (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> עד למילוי)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"בטעינה איטית (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> עד למילוי)"</string>
@@ -485,14 +484,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"דף הבית"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"אחרונים"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"הקודם"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"הצג את החלונית \'נא לא להפריע\' בעוצמת הקול"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"אפשר שליטה מלאה בחלונית \'נא לא להפריע\' בתיבת הדו-שיח של עוצמת הקול."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"עוצמת הקול והאפשרות \'נא לא להפריע\'"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"היכנס לאפשרות \'נא לא להפריע\' בהחלשת עוצמת הקול"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"צא מהאפשרות \'נא לא להפריע\' בהגברת עוצמת הקול"</string>
+    <string name="battery" msgid="7498329822413202973">"סוללה"</string>
+    <string name="clock" msgid="7416090374234785905">"שעון"</string>
+    <string name="headset" msgid="4534219457597457353">"אוזניות"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"אוזניות מחוברות"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"אוזניות מחוברות"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"הפעלה או השבתה של סמלים המוצגים בשורת הסטטוס."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings_car.xml b/packages/SystemUI/res/values-iw/strings_car.xml
new file mode 100644
index 0000000..8d62258
--- /dev/null
+++ b/packages/SystemUI/res/values-iw/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"נסיעה בטוחה"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏עליך להיות מודע לתנאי הנהיגה באופן מלא, ולציית תמיד לדינים החלים. ייתכן שהמסלול אינו מדויק, לא שלם, מסוכן, לא מתאים, אסור למעבר או כרוך בחציית אזורים מנהליים. ייתכן שגם מידע עסקי לא יהיה מדויק או שלם. הנתונים אינם מדווחים בזמן אמת ולא ניתן להבטיח דיוק במיקום. אל תתעסק במכשיר הנייד שלך ואל תשתמש באפליקציות שאינן מיועדות ל-Android Auto בזמן הנהיגה."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 5f448bf..189fcd9 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"重要な\n通知のみ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"アラーム\nのみ"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"すべて"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"すべて\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"充電中(フル充電まで<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"急速充電中(完了まで<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"低速充電中(完了まで<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ホーム"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"戻る"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"音量内に [通知を非表示] を表示"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"音量ダイアログでの [通知を非表示] の管理を許可します。"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"音量と [通知を非表示]"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"音量下げボタンで [通知を非表示] を ON にする"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"音量上げボタンで [通知を非表示] を OFF にする"</string>
+    <string name="battery" msgid="7498329822413202973">"電池"</string>
+    <string name="clock" msgid="7416090374234785905">"時計"</string>
+    <string name="headset" msgid="4534219457597457353">"ヘッドセット"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ヘッドホンを接続しました"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ヘッドセットを接続しました"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"ステータスバーでのアイコンの表示を有効または無効にします。"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings_car.xml b/packages/SystemUI/res/values-ja/strings_car.xml
new file mode 100644
index 0000000..667de81
--- /dev/null
+++ b/packages/SystemUI/res/values-ja/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"安全運転を心がけましょう"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"道路状況に十分気を配り、適用される法律を遵守してください。経路は、不正確、不完全、危険、不適切である場合や、通行が禁止されている、管理区域を通行する必要があるなどの場合があります。ビジネス情報も不正確または不完全である可能性があります。データはリアルタイムではなく、場所の正確性は保証されません。運転中はモバイル端末を手に持って操作したり、Android Auto とは無関係のアプリを使用したりしないでください。"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 38fd4b3..07390f5 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"მხოლოდ\nპრიორიტეტულები"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"მხოლოდ\nგაფრთხილებები"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"ყველა"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"ყველა\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>-ის შეცვლა დასრულებამდე)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"იტენება სწრაფად (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> სრულ დატენვამდე)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"იტენება ნელა (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> სრულ დატენვამდე)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"მთავარი"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ბოლოს გამოყენებული"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"უკან"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"ხმის დიალოგში „არ შემაწუხოთ“ რეჟიმის ჩვენება"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"ხმის დიალოგში „არ შემაწუხოთ“ რეჟიმის სრული კონტროლის დაშვება."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ხმა და „არ შემაწუხოთ“"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"ხმის დაწევისას „არ შემაწუხოთ“ რეჟიმზე გადასვლა"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ხმის აწევისას „არ შემაწუხოთ“ რეჟიმიდან გამოსვლა"</string>
+    <string name="battery" msgid="7498329822413202973">"ბატარეა"</string>
+    <string name="clock" msgid="7416090374234785905">"საათი"</string>
+    <string name="headset" msgid="4534219457597457353">"ყურსაცვამი"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ყურსასმენები დაკავშირებულია"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ყურსაცვამი დაკავშირებულია"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"სტატუსის ზოლში ხატულების ჩვენების ჩართვა ან გათიშვა."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings_car.xml b/packages/SystemUI/res/values-ka-rGE/strings_car.xml
new file mode 100644
index 0000000..c8e17dd
--- /dev/null
+++ b/packages/SystemUI/res/values-ka-rGE/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"უსაფრთხოდ მართვის წესები"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ყოველთვის გულდასმით გაეცანით მდგომარეობას გზებზე და დაიცავით მოქმედი კანონები. შეთავაზებული მიმართულებები შეიძლება იყოს უზუსტო, არასრული, სახიფათო, შეუფერებელი, აკრძალული, ან ადმინისტრაციული ერთეულების გადაკვეთას გულისხმობდეს. ბიზნეს-ინფორმაცია შეიძლება ასევე იყოს უზუსტო ან არასრული. მონაცემების განახლება რეალური დროის რეჟიმში არ ხდება და შესაბამისად, მდებარეობის სიზუსტე გარანტირებული ვერ იქნება. ავტომობილის მართვისას ნუ შეეცდებით თქვენი მობილური მოწყობილობით მანიპულირებას, ან ისეთი აპების გამოყენებას, რომლებიც Android Auto-სთვის შექმნილი არ არის."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index f1d96b2..02e773c 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Тек\nбасымдық"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Тек\nдабылдар"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Барлығы"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Барлығы\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Зарядталуда (толғанша <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Жылдам зарядталуда (толғанша <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Баяу зарядталуда (толғанша <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Негізгі бет"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Жақындағылар"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Артқа"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Дыбыс деңгейінде \"Мазаламау\" режимін көрсету"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Дыбыс деңгейі диалогтық терезесінде \"Мазаламау\" режимін толық басқаруға рұқсат ету."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Дыбыс деңгейі және \"Мазаламау\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Дыбыс деңгейін төмендеткенде \"Мазаламау\" режиміне кіру"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Дыбыс деңгейін көтергенде \"Мазаламау\" режимінен шығу"</string>
+    <string name="battery" msgid="7498329822413202973">"Батарея"</string>
+    <string name="clock" msgid="7416090374234785905">"Сағат"</string>
+    <string name="headset" msgid="4534219457597457353">"Құлақаспап жинағы"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Құлақаспап қосылды"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Құлақаспап жинағы қосылды"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Белгішелердің күй жолағында көрсетілуін қосу немесе өшіру"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings_car.xml b/packages/SystemUI/res/values-kk-rKZ/strings_car.xml
new file mode 100644
index 0000000..056b75c
--- /dev/null
+++ b/packages/SystemUI/res/values-kk-rKZ/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Қауіпсіз жүргізу"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Жүргізу жағдайларын толығымен ұғыныңыз және тиісті заңдарды әрқашан сақтаңыз. Бағыттар дәл емес, толық емес, қауіпті, жарамсыз, тыйым салынған болуы немесе әкімшілік аумақтарды қиып өтуі мүмкін. Іскери ақпарат та дәл емес немесе толық емес болуы мүмкін. Деректер нақты уақыттағы деректер емес және орын дәлдігіне кепілдік берілмейді. Жүргізу кезінде мобильді құрылғыңызды ұстамаңыз немесе Android Auto қолданбасына арналмаған қолданбаларды пайдаланбаңыз."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 7f5b0d8..513a5b8 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"អាទិភាព\nប៉ុណ្ណោះ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"សំឡេងរោទ៍\nប៉ុណ្ណោះ"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"ទាំងអស់"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"ទាំងអស់\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"កំពុង​បញ្ចូល​ថ្ម (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ទើប​ពេញ)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ថ្មកំពុងសាកលឿន (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ទើបពេញ)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ថ្មកំពុងសាកយឺតៗ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ទើបពេញ)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ដើម"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ថ្មីៗ"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ថយក្រោយ"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"បង្ហាញមុខងារកុំរំខាននៅក្នុងកម្រិតសំឡេង"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"អនុញ្ញាតឲ្យមានការគ្រប់គ្រងពេញលេញចំពោះមុខងារកុំរំខាននៅក្នុងប្រអប់កម្រិតសំឡេង។"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"កម្រិតសំឡេង និងមុនងារកុំរំខាន"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"ចូលមុខងារកុំរំខាននៅពេលបន្ថយសំឡេង"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ចាកចេញពីមុខងារកុំរំខាននៅពេលបង្កើនសំឡេង"</string>
+    <string name="battery" msgid="7498329822413202973">"ថ្ម"</string>
+    <string name="clock" msgid="7416090374234785905">"នាឡិកា"</string>
+    <string name="headset" msgid="4534219457597457353">"កាស"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"បានភ្ជាប់កាស"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"បានភ្ជាប់កាស"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"បើក ឬបិទដំណើរការបង្ហាញរូបតំណាងនៅលើរបារស្ថានភាព"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings_car.xml b/packages/SystemUI/res/values-km-rKH/strings_car.xml
new file mode 100644
index 0000000..9648a5fb
--- /dev/null
+++ b/packages/SystemUI/res/values-km-rKH/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"បើកបរដោយសុវត្ថិភាព"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ត្រូវមានការគ្រប់គ្រងពេញលេញលើស្ថានភាពបើកបរ និងគោរពច្បាប់ដែលត្រូវអនុវត្តជានិច្ច។ ទិសដៅអាចនឹងមិនមានភាពសុក្រិត មិនពេញលេញ គ្រោះថ្នាក់ មិនសមស្រប ឬពាក់ព័ន្ធនឹងការឆ្លងកាត់តំបន់រដ្ឋបាល។ ព័ត៌មានផ្នែកអាជីវកម្មក៏អាចនឹងមិនមានភាពសុក្រិត ឬមិនពេញលេញផងដែរ។ ទិន្នន័យគឺមិនមែនបញ្ជូនបន្តផ្ទាល់នោះទេ ហើយភាពសុក្រិតនៃទីតាំងក៏មិនអាចធានាបានផងដែរ។ កុំកាន់ឧបករណ៍ចល័តរបស់អ្នក ឬប្រើកម្មវិធីដែលមិនមែនសម្រាប់ Android Auto ខណៈពេលកំពុងបើកបរ។"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index e238e53..a64fe5a 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ಆದ್ಯತೆ\nಮಾತ್ರ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ಅಲಾರಮ್‌ಗಳು\nಮಾತ್ರ"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"ಎಲ್ಲ"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"ಎಲ್ಲಾ\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ ( ಪೂರ್ತಿ ಆಗುವವರೆಗೆ <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ವೇಗವಾಗಿ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ (ಪೂರ್ಣಗೊಳ್ಳಲು <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ನಿಧಾನ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ (ಪೂರ್ಣಗೊಳ್ಳಲು <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ಮುಖಪುಟ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ಇತ್ತೀಚಿನವುಗಳು"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ಹಿಂದೆ"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ \"ಅಡಚಣೆ ಮಾಡಬೇಡಿ\" ಅನ್ನು ತೋರಿಸಿ"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"ವಾಲ್ಯೂಮ್ ಸಂವಾದದಲ್ಲಿ \"ಅಡಚಣೆ ಮಾಡಬೇಡಿ\"ಯ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣವನ್ನು ಅನುಮತಿಸಿ."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ವಾಲ್ಯೂಮ್‌ ಮತ್ತು ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"ವಾಲ್ಯೂಮ್ ಕಡಿಮೆಯಲ್ಲಿ \"ಅಡಚಣೆ ಮಾಡಬೇಡಿ\" ನಮೂದಿಸಿ"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ವಾಲ್ಯೂಮ್ ಹೆಚ್ಚಳದಲ್ಲಿ \"ಅಡಚಣೆ ಮಾಡಬೇಡಿ\"ಯನ್ನು ತೊರೆಯಿರಿ"</string>
+    <string name="battery" msgid="7498329822413202973">"ಬ್ಯಾಟರಿ"</string>
+    <string name="clock" msgid="7416090374234785905">"ಗಡಿಯಾರ"</string>
+    <string name="headset" msgid="4534219457597457353">"ಹೆಡ್‌ಸೆಟ್"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ಹೆಡ್‌ಫೋನ್ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ಹೆಡ್‌ಸೆಟ್ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಲ್ಲಿ ಐಕಾನ್‌ಗಳು ತೋರಿಸುವುದನ್ನು ಸಕ್ರಿಯ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings_car.xml b/packages/SystemUI/res/values-kn-rIN/strings_car.xml
new file mode 100644
index 0000000..e8e99c4
--- /dev/null
+++ b/packages/SystemUI/res/values-kn-rIN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ಸುರಕ್ಷಿತವಾಗಿ ಚಾಲನೆ ಮಾಡಿ"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ಚಾಲನೆ ಸ್ಥಿತಿಗಳ ಕುರಿತು ಸಂಪೂರ್ಣವಾಗಿ ತಿಳಿದುಕೊಳ್ಳಿ ಮತ್ತು ಅನ್ವಯವಾಗುವ ಕಾನೂನುಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಸರಿಸಿ. ದಿಕ್ಕುಗಳು ಸರಿಯಾಗಿ ಇಲ್ಲದಿರಬಹುದು, ಅಪೂರ್ಣವಾಗಿರಬಹುದು, ಅಪಾಯಕಾರಿಯಾಗಿರಬಹುದು, ಸೂಕ್ತವಾಗಿಲ್ಲದಿರಬಹುದು, ನಿಷೇಧಿಸಿರಬಹುದು ಅಥವಾ ನಿರ್ವಹಣೆ ಪ್ರದೇಶಗಳ ಮೂಲಕ ಹಾದು ಹೋಗಬೇಕಾಗಬಹುದು. ವ್ಯಾಪಾರ ಮಾಹಿತಿಯು ಸಹ ತಪ್ಪಾಗಿರಬಹುದು ಅಥವಾ ಅಪೂರ್ಣವಾಗಿರಬಹುದು. ಡೇಟಾ ನೈಜ ಸಮಯದ್ದಾಗಿರದಿರಬಹುದು ಮತ್ತು ಸ್ಥಳ ನಿಖರತೆಗೆ ಖಾತ್ರಿ ನೀಡಲಾಗುವುದಿಲ್ಲ. ನಿಮ್ಮ ಮೊಬೈಲ್ ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಬೇಡಿ ಅಥವಾ ಚಾಲನೆ ಮಾಡುತ್ತಿರುವಾಗ Android Auto ಗೆ ಅಲ್ಲದಿರುವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬಳಸಬೇಡಿ."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 725bd18..30a9422 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"중요 알림만\n허용"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"알람만\n"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"모두 수신"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"모두\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"충전 중(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> 후 충전 완료)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"고속 충전 중(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> 후 충전 완료)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"저속 충전 중(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> 후 충전 완료)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"홈"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"최근"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"뒤로"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"볼륨에 알림 일시중지 표시"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"볼륨 대화상자에서 알림 일시중지에 대한 전체 컨트롤을 허용합니다."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"볼륨 및 알림 일시중지"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"볼륨 작게 시 알림 일시중지 사용"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"볼륨 크게 시 알림 일시중지 종료"</string>
+    <string name="battery" msgid="7498329822413202973">"배터리"</string>
+    <string name="clock" msgid="7416090374234785905">"시계"</string>
+    <string name="headset" msgid="4534219457597457353">"헤드셋"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"헤드폰 연결됨"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"헤드셋 연결됨"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"아이콘이 상태 표시줄에 표시되도록 사용 설정 또는 중지합니다."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings_car.xml b/packages/SystemUI/res/values-ko/strings_car.xml
new file mode 100644
index 0000000..e18e587
--- /dev/null
+++ b/packages/SystemUI/res/values-ko/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"안전 운전"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"도로 상황에 주의를 기울이고 관련 법규를 항상 준수하세요. 길찾기는 부정확하거나 불완전하거나 위험하거나 부적당하거나 금지되거나 여러 행정구역에 걸친 지역을 지나도록 안내할 수 있습니다. 비즈니스 정보 또한 부정확하거나 불완전할 수 있습니다. 데이터는 실시간이 아니며 위치의 정확도를 보증할 수 없습니다. 운전 중에 휴대기기를 조작하거나 Android Auto가 지원되지 않는 앱을 사용해서는 안 됩니다."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 539cc7e..873cf37 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Артыкчылыктуу\nгана"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ойготкучтар\nгана"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Бардыгы"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Бардык\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Кубатталууда (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> толгонго чейин)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Тез кубатталууда (толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> калды)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Жай кубатталууда (толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> калды)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Башкы бет"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Акыркылар"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Артка"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"\"Тынчымды алба\" режимин үн көзөмөлдөгүчүндө көрсөтүү"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Үндү катуулатып/акырындатуу диалогунда \"Тынчымды алба\" режимин толук көзөмөлдөөгө уруксат берүү."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Үн көзөмөлдөгүчү жана \"Тынчымды алба\" режими"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Үн акырындатылганда \"Тынчымды алба\" режимине кирүү"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Үн катуулатылганда \"Тынчымды алба\" режиминен чыгуу"</string>
+    <string name="battery" msgid="7498329822413202973">"Батарея"</string>
+    <string name="clock" msgid="7416090374234785905">"Саат"</string>
+    <string name="headset" msgid="4534219457597457353">"Гарнитура"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Гарнитуралар туташкан"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Гарнитура туташты"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Абал тилкесиндеги сүрөтчөнү иштетүү же өчүрүү."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings_car.xml b/packages/SystemUI/res/values-ky-rKG/strings_car.xml
new file mode 100644
index 0000000..1d99ff2
--- /dev/null
+++ b/packages/SystemUI/res/values-ky-rKG/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Коопсуздук эрежелерин сактаңыз"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Унаа айдап бара жатканда жолдогу шарттар менен эрежелерге ар дайым көңүл буруңуз. Багыттар так же толук эмес берилип, кесип өтүү үчүн опурталдуу же ылайыксыз болгон административдик аймактар аркылуу өтүшү мүмкүн. Ишканалар тууралуу маалымат да так же толук эмес болушу мүмкүн. Дайындар тез-тез жаңыртылып турбагандыктан, жайгашкан жердин так аныкталгандыгына кепилдик жок. Андыктан унаа айдап бара жатканда, мобилдик түзмөгүңүздү же Android Auto\'го арналбаган колдонмолорду пайдаланбаңыз."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index b75e398..7a85446 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ບຸ​ລິ​ມະ​ສິດ\nເທົ່າ​ນັ້ນ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ໂມງ​ປຸກ\nເທົ່າ​ນັ້ນ"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"ທັງໝົດ"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"ທັງໝົດ\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ກຳ​ລັງ​ສາກ​ໄຟ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ກວ່າ​ຈ​ະ​ເຕັມ)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ກຳ​ລັງ​ສາກ​ໄຟ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ກວ່າ​ຈ​ະ​ເຕັມ)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"ກຳ​ລັງ​ສາກ​ໄຟ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ກວ່າ​ຈ​ະ​ເຕັມ)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"​ໜ້າຫຼັກ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ຫາ​ກໍ​ໃຊ້"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ກັບຄືນ"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"ສະແດງ ຫ້າມລົບກວນ ໃນລະດັບສຽງ"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"ອະນຸຍາດການຄວບຄຸມເຕັມສ່ວນຂອງ ຫ້າມລົບກວນ ໃນກ່ອງປັບລະດັບສຽງ."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ລະດັບສຽງ ແລະ ຫ້າມລົບກວນ"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"ເປີດໃຊ້ໂໝດ ຫ້າມລົບກວນ ເມື່ອປັບສຽງໃຫ້ຄ່ອຍລົງ"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ອອກຈາກໂໝດ ຫ້າມລົບກວນ ເມື່ອປັບສຽງໃຫ້ດັງຂຶ້ນ"</string>
+    <string name="battery" msgid="7498329822413202973">"ແບັດເຕີຣີ"</string>
+    <string name="clock" msgid="7416090374234785905">"ໂມງ"</string>
+    <string name="headset" msgid="4534219457597457353">"​ຊຸດ​ຫູ​ຟັງ"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ເຊື່ອມຕໍ່ຊຸດຫູຟັງແລ້ວ"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ເຊື່ອມ​ຕໍ່ຊຸດ​ຫູ​ຟັງແລ້ວ"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"ເປີດ ຫຼື ປິດໄອຄອນຕ່າງໆຈາກການສະແດງໃນແຖບສະຖານະ."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings_car.xml b/packages/SystemUI/res/values-lo-rLA/strings_car.xml
new file mode 100644
index 0000000..3388f54
--- /dev/null
+++ b/packages/SystemUI/res/values-lo-rLA/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ຂັບຂີ່ຢ່າງປອດໄພ"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ຮູ້ຈັກສະພາບການຂັບຂີ່ຢ່າງຄົບຖ້ວນ ແລະ ປະຕິບັດຕາມກົດໝາຍທີ່ນຳໃຊ້ສະເໝີ. ຄຳແນະນຳເສັ້ນທາງອາດຈະບໍ່ຖືກຕ້ອງ, ບໍ່ຄົບຖ້ວນ, ອັນຕະລາຍ, ບໍ່ເໝາະສົມ, ຖືກຫ້າມ ຫຼື ກ່ຽວຂ້ອງກັບການຂ້າມເຂດປົກຄອງ. ຂໍ້ມູນທຸລະກິດອາດຈະບໍ່ຖືກຕ້ອງ ຫຼື ບໍ່ຄົບຖ້ວນ. ຂໍ້ມູນບໍ່ແມ່ນຂໍ້ມູນສົດ ແລະ ບໍ່ສາມາດຮັບປະກັນຄວາມຖືກຕ້ອງຂອງສະຖານທີ່ໄດ້. ຢ່າໃຊ້ອຸປະກອນມືຖືຂອງທ່ານ ຫຼື ໃຊ້ແອັບທີ່ບໍ່ມີໄວ້ສຳລັບ Android Auto ໃນຂະນະທີ່ຂັບຂີ່."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index e79e6d3..c9a5959 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -334,8 +334,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Tik\nprioritetiniai"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Tik\nsignalai"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Visi"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Visi\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Greitai kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lėtai kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
@@ -485,14 +484,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pagrindinis ekranas"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Naujausios veiklos ekranas"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atgal"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Rodyti netrukdymo režimą garsumo dialogo lange"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Leisti visiškai valdyti netrukdymo režimą garsumo dialogo lange."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Garsumas ir netrukdymo režimas"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Įjungti netrukdymo režimą mažinant garsumą"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Išjungti netrukdymo režimą didinant garsumą"</string>
+    <string name="battery" msgid="7498329822413202973">"Akumuliatorius"</string>
+    <string name="clock" msgid="7416090374234785905">"Laikrodis"</string>
+    <string name="headset" msgid="4534219457597457353">"Ausinės"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Ausinės prijungtos"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Ausinės prijungtos"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Įgalinti arba išjungti piktogramų rodymą būsenos juostoje."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings_car.xml b/packages/SystemUI/res/values-lt/strings_car.xml
new file mode 100644
index 0000000..03d656a
--- /dev/null
+++ b/packages/SystemUI/res/values-lt/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Vairuokite saugiai"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Visada atsižvelkite į vairavimo sąlygas ir laikykitės galiojančių įstatymų. Nuorodos gali būti netikslios, neužbaigtos, pavojingos, netinkamos, draudžiamos ar nukreipiančios per administracines sritis. Įmonių informacija taip pat gali būti netiksli ar neužbaigta. Duomenys nėra teikiami realiuoju laiku ir vietovių tikslumo negalima garantuoti. Vairuodami nenaudokite mobiliojo įrenginio ar programų, kurios nėra skirtos „Android Auto“."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 3b27424..5e115a8 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -333,8 +333,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Tikai\nprioritārie"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Tikai\nsignāli"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Visi"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Visi\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Notiek uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Ātra uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lēna uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
@@ -484,14 +483,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Sākums"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Pēdējie"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atpakaļ"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Rādīt režīmu “Netraucēt” skaļuma regulēšanas dialoglodziņā"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Atļaujiet pilnu režīma “Netraucēt” kontroli skaļuma regulēšanas dialoglodziņā."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Skaļums un režīms “Netraucēt”"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Ieslēgt režīmu “Netraucēt”, samazinot skaļumu"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Izslēgt režīmu “Netraucēt”, palielinot skaļumu"</string>
+    <string name="battery" msgid="7498329822413202973">"Akumulators"</string>
+    <string name="clock" msgid="7416090374234785905">"Pulkstenis"</string>
+    <string name="headset" msgid="4534219457597457353">"Austiņas"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Austiņas ir pievienotas"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Austiņas ar mikrofonu ir pievienotas"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Iespējojiet vai atspējojiet ikonu rādīšanu statusa joslā."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings_car.xml b/packages/SystemUI/res/values-lv/strings_car.xml
new file mode 100644
index 0000000..0171624
--- /dev/null
+++ b/packages/SystemUI/res/values-lv/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Droša braukšana"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Pievērsiet visu uzmanību braukšanas apstākļiem un vienmēr ievērojiet piemērojamos tiesību aktus. Norādes var būt neprecīzas, nepilnīgas, bīstamas, nepiemērotas, aizliegtas vai var ietvert administratīvo teritoriju šķērsošanu. Arī uzņēmumu informācija var būt neprecīza vai nepilnīga. Dati netiek nodrošināti reāllaikā, un netiek garantēta atrašanās vietu precizitāte. Vadot transportlīdzekli, nelietojiet mobilo ierīci rokās un neizmantojiet lietotnes, kas nav paredzētas pakalpojumam Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 85832df..348d679 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Јачина на звук и „Не вознемирувај“"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"Премини во „Не вознемирувај“ при намалена јачина на звукот"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"Излези од „Не вознемирувај“ при зголемена јачина на звукот"</string>
+    <string name="battery" msgid="7498329822413202973">"Батерија"</string>
+    <string name="clock" msgid="7416090374234785905">"Часовник"</string>
+    <string name="headset" msgid="4534219457597457353">"Слушалки"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Слушалките се поврзани"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Слушалките се поврзани"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Овозможете или оневозможете прикажување на иконите во статусната лента."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings_car.xml b/packages/SystemUI/res/values-mk-rMK/strings_car.xml
new file mode 100644
index 0000000..f5ed824
--- /dev/null
+++ b/packages/SystemUI/res/values-mk-rMK/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Возете безбедно"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Секогаш бидете известени за условите за возење и почитувајте ги важечките закони. Насоките може да бидат неточни, нецелосни, опасни, несоодветни, забранети или да вклучуваат премин преку административни области. Бизнис информациите исто така може да бидат неточни или нецелосни. Податоците не се даваат во реално време и не може да се гарантира точноста на локацијата. Не ракувајте со вашиот мобилен уред и не користете апликации што не се наменети за Android Auto додека возите."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index b2d7b9d..a393e42 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"മുൻഗണന\nമാത്രം"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"അലാറങ്ങൾ\nമാത്രം"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"എല്ലാം"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"എല്ലാം\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ചാർജ്ജുചെയ്യുന്നു (പൂർണ്ണമാകുന്നതിന്, <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"വേഗത്തിൽ ചാർജുചെയ്യുന്നു (പൂർണ്ണമാകാൻ <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"പതുക്കെ ചാർജുചെയ്യുന്നു (പൂർണ്ണമാകാൻ <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"വീട്"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"പുതിയവ"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"മടങ്ങുക"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"വോളിയത്തിൽ \'ശല്യപ്പെടുത്തരുത്\' കാണിക്കുക"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"വോളിയം ഡയലോഗിൽ \'ശല്യപ്പെടുത്തരുത്\' എന്നത് പൂർണ്ണമായി നിയന്ത്രിക്കാൻ അനുവദിക്കുക."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"വോളിയവും \'ശല്യപ്പെടുത്തരുത്\' എന്നതും"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"വോളിയം താഴുമ്പോൾ \'ശല്യപ്പെടുത്തരുത്\' പ്രവർത്തിപ്പിക്കുക"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"വോളിയം ഉയരുമ്പോൾ \'ശല്യപ്പെടുത്തരുത്\' നിർത്തുക"</string>
+    <string name="battery" msgid="7498329822413202973">"ബാറ്ററി"</string>
+    <string name="clock" msgid="7416090374234785905">"ക്ലോക്ക്"</string>
+    <string name="headset" msgid="4534219457597457353">"ഹെഡ്‌സെറ്റ്"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ഹെഡ്ഫോണുകൾ കണക്റ്റുചെയ്തു"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ഹെഡ്‌സെറ്റ് കണക്‌റ്റുചെയ്‌തു"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"സ്റ്റാറ്റസ് ബാറിൽ കാണിക്കുന്നതിൽ നിന്ന് ഐക്കണുകളെ പ്രവർത്തനക്ഷമമാക്കുകയോ പ്രവർത്തനരഹിതമാക്കുകയോ ചെയ്യുക"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings_car.xml b/packages/SystemUI/res/values-ml-rIN/strings_car.xml
new file mode 100644
index 0000000..b53029c
--- /dev/null
+++ b/packages/SystemUI/res/values-ml-rIN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"സുരക്ഷിതമായി ഡ്രൈവ് ചെയ്യുക"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ഡ്രൈവിംഗ് സാഹചര്യങ്ങളെ കുറിച്ച് നല്ലവണ്ണം അറിഞ്ഞുവയ്ക്കുക, എല്ലായ്പ്പോഴും ബാധകമായ നിയമങ്ങൾ അനുസരിക്കുക. ദിശാസൂചനകൾ കൃത്യമല്ലാത്തതും അപൂർണ്ണവും അപകടകരവും അനുയോജ്യമല്ലാത്തതും നിരോധിക്കപ്പെട്ടതും അഡ്‌മിനിസ്ട്രേറ്റീവ് ഏരിയകൾ അതിലംഘിച്ച് പോകേണ്ടതുമായിരിക്കാം. വിവരങ്ങൾ തത്സമയം എടുത്തിട്ടുള്ളതല്ല, അതിനാൽ ലൊക്കേഷൻ കൃത്യത ഉറപ്പാക്കാൻ കഴിയില്ല. ഡ്രൈവ് ചെയ്യുന്ന സമയത്ത് മൊബൈൽ ഉപകരണങ്ങളോ Android Auto-യ്ക്കായി ഉദ്ദേശിക്കപ്പെട്ടിട്ടില്ലാത്ത ആപ്‌സോ കൈകാര്യം ചെയ്യരുത്"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 2e8126e..9b45994 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -330,8 +330,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Зөвхөн\nхамгийн чухлыг"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Зөвхөн\nсэрүүлэг"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Бүгд"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Бүх\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Цэнэглэж байна (дүүргэхэд <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Цэнэглэж байна (дүүргэхэд <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> шаардлагатай)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Цэнэглэж байна (дүүргэхэд <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> шаардлагатай)"</string>
@@ -481,14 +480,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Нүүр хуудас"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Саяхны"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Буцах"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Бүү саад бол тохиргоог дууны түвшинд харуулах"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Бүү саад бол тохиргооны бүрэн хяналтыг дууны түвшний харилцах цонхонд зөвшөөрнө үү."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Дууны түвшин болон бүү саад бол тохиргоо"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Бүү саад бол тохиргоог оруулахын тулд дууны түвшинг бууруулах"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Бүү саад бол тохиргооноос гарахын тулд дууны түвшинг нэмэх"</string>
+    <string name="battery" msgid="7498329822413202973">"Зай"</string>
+    <string name="clock" msgid="7416090374234785905">"Цаг"</string>
+    <string name="headset" msgid="4534219457597457353">"Чихэвч"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Чихэвч холбогдсон"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Чихэвч холбогдсон"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Статусын самбарт харагдах дүрс тэмдгийг идэвхжүүлэх эсвэл идэвхгүй болгоно уу."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings_car.xml b/packages/SystemUI/res/values-mn-rMN/strings_car.xml
new file mode 100644
index 0000000..d48580f
--- /dev/null
+++ b/packages/SystemUI/res/values-mn-rMN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Жолооны аюулгүй байдал"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Жолоодох нөхцөлийн талаар бүрэн ойлгож, холбогдох дүрэм журмыг мөрдөөрэй. Чиглэл нь тодорхой бус, гүйцэт бус, аюултай, тохиромжгүй, хориглосон эсвэл тусгай хамгаалалттай газар нутагт нэвтэрсэн байж болзошгүй. Бизнесийн мэдээлэл мөн адил тохиромжгүй эсвэл гүйцэт бус байна. Өгөгдөл нь тухайн цаг хугацааных биш учир байршлыг зөв тодорхойлсон эсэхийг батлах боломжгүй. Жолоодож байхдаа гар утсаа болон Android Автод зориулаагүй апп-г бүү ашиглаарай."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 846e7ee..9329909 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"केवळ\nप्राधान्य"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"केवळ\nअलार्म"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"सर्व"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"सर्व\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण होईपर्यंत) चार्ज होत आहे"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण होईपर्यंत) वेगाने चार्ज होत आहे"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण होईपर्यंत) हळूहळू चार्ज होत आहे"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"मुख्यपृष्ठ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"अलीकडील"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"परत"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"आवाजामध्‍ये व्यत्यय आणू नका दर्शवा"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"आवाज संवादामधील व्यत्यय आणू नका च्या पूर्ण नियंत्रणास अनुमती द्या."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"आवाज आणि व्यत्यय आणू नका"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"आवाज कमी केल्यावर व्यत्यय आणू नका प्रविष्‍ट करा"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"आवाज वाढविल्यावर व्यत्यय आणू नका मधून बाहेर पडा"</string>
+    <string name="battery" msgid="7498329822413202973">"बॅटरी"</string>
+    <string name="clock" msgid="7416090374234785905">"घड्याळ"</string>
+    <string name="headset" msgid="4534219457597457353">"हेडसेट"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"हेडफोन कनेक्ट केले"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"हेडसेट कनेक्ट केला"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"चिन्हे स्टेटस बारमध्ये दर्शविले जाण्‍यापासून प्रतिबंधित करण्‍यासाठी ती सक्षम किंवा अक्षम करा."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings_car.xml b/packages/SystemUI/res/values-mr-rIN/strings_car.xml
new file mode 100644
index 0000000..7dc5d17
--- /dev/null
+++ b/packages/SystemUI/res/values-mr-rIN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"सुरक्षितपणे वाहन चालवा"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"वाहन चालविण्‍याच्या शर्तींची पूर्णपणे माहिती असू द्या आणि नेहमी लागू असलेल्या कायद्यांचे पालन करा. दिशानिर्देश कदाचित चुकीचे, अपूर्ण, धोकादायक, अनुकूल नसलेले, प्रतिबंधित किंवा प्रशासकीय क्षेत्रांना ओलांडणारे असू शकतात. व्यवसाय माहिती देखील चुकीची किंवा अपूर्ण असू शकते. डेटा हा रिअल-टाइम नसतो आणि स्थान अचूकतेची हमी दिली जाऊ शकत नाही. वाहन चालविताना Android Auto च्या उद्देशासाठी नसलेले आपले मोबाईल डिव्हाइस हाताळू नका किंवा अॅप्स वापरू नका."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index dd5f767..a4e90c0 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Keutamaan\nsahaja"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Penggera\nsahaja"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Semua"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Semua\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Mengecas (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Mengecas cepat (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mengecas perlahan (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Skrin Utama"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaharu"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Kembali"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Tunjukkan jangan ganggu dalam kelantangan"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Benarkan kawalan penuh jangan ganggu dalam dialog kelantangan."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Kelantangan dan Jangan Ganggu"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Masuki mod jangan ganggu apabila kelantangan direndahkan"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Keluar drp mod jangan ganggu apabila kelantangan ditinggikan"</string>
+    <string name="battery" msgid="7498329822413202973">"Bateri"</string>
+    <string name="clock" msgid="7416090374234785905">"Jam"</string>
+    <string name="headset" msgid="4534219457597457353">"Set Kepala"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Fon kepala disambungkan"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Set kepala disambungkan"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Dayakan atau lumpuhkan ikon daripada dipaparkan dalam bar status."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings_car.xml b/packages/SystemUI/res/values-ms-rMY/strings_car.xml
new file mode 100644
index 0000000..392530a
--- /dev/null
+++ b/packages/SystemUI/res/values-ms-rMY/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Pandu dengan selamat"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Pastikan anda sentiasa sedar sepenuhnya akan keadaan pemanduan dan mematuhi undang-undang yang dikenakan pada sepanjang masa. Arah mungkin tidak tepat, tidak lengkap, berbahaya, tidak sesuai, dilarang atau melibatkan lintasan kawasan pentadbiran. Maklumat perniagaan juga mungkin tidak tepat atau tidak lengkap. Data bukan masa sebenar dan ketepatan lokasi tidak dapat dijamin. Jangan kendalikan peranti mudah alih anda atau gunakan apl yang bukan untuk Android Auto semasa memandu."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 4bb3a45..cfcc15ab 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ဦးစားပေးမှု\nသာ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"နှိုးစက်များ\nသာ"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"အားလုံး"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"အားလုံး\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> အပြည့် အထိ) အားသွင်းနေ"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"လျှင်မြန်စွာအားသွင်းခြင်း (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ပြည့်သည်အထိ)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"နှေးကွေးစွာ အားသွင်းခြင်း (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ပြည့်သည်အထိ)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ပင်မ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"မကြာသေးခင်က"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"နောက်သို့"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"အသံအတိုးအလျှော့တွင် မနှောက်ယှက်ရကို ပြပါ"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"အသံအတိုးအလျှော့အကွက်ထဲတွင် မနှောက်ယှက်ရကို အပြည့်အဝထိန်းချုပ်ခွင့် ပြုပါ။"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"အသံအတိုးအလျှော့နှင့် မနှောက်ယှက်ရ"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"အသံလျှော့သည်နှင့် မနှောက်ယှက်ရသို့ ပြောင်းလဲပါ"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"အသံချဲ့သည်နှင့် မနှောက်ယှက်ရမှ ထွက်ပါ"</string>
+    <string name="battery" msgid="7498329822413202973">"ဘတ်ထရီ"</string>
+    <string name="clock" msgid="7416090374234785905">"နာရီ"</string>
+    <string name="headset" msgid="4534219457597457353">"မိုက်ခွက်ပါနားကြပ်"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"နားကြပ်တပ်ဆင်ပြီးပါပြီ"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"မိုက်ခွက်ပါနားကြပ်တပ်ဆင်ပြီးပါပြီ"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"အခြေအနေဘားတန်းတွင် သင်္ကေတပုံပြခြင်းကို ဖွင့်ရန် သို့မဟုတ် ပိတ်ရန်"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings_car.xml b/packages/SystemUI/res/values-my-rMM/strings_car.xml
new file mode 100644
index 0000000..dd41713
--- /dev/null
+++ b/packages/SystemUI/res/values-my-rMM/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ဘေးကင်းလုံခြုံစွာ မောင်းနှင်ပါ"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ယာဉ်မောင်းမှုအခြေအနေများကို အပြည့်အဝအာရုံစိုက်ပြီး သက်ဆိုင်ရာဥပဒေများကို အမြဲတမ်းလိုက်နာပါ။ လမ်းညွှန်ချက်များသည် မှန်ကန်မှုမရှိခြင်း၊ မပြည့်စုံခြင်း၊ အန္တရာယ်ရှိခြင်း၊ ကိုက်ညီမှုမရှိခြင်း၊ တားမြစ်ထားခြင်း၊ သို့မဟုတ် လမ်းဖြတ်ကူးခြင်း ကြီးကြပ်ထားသည့်နေရာများ ဖြစ်နေနိုင်ပါသည်။ စီးပွားရေးအချက်အလက်များသည်လည်း မမှန်ကန်ခြင်း သို့မဟုတ် မပြည့်စုံခြင်းများ ရှိနိုင်ပါသည်။ ဒေတာသည် အချိန်နှင့်တစ်ပြေးညီ မဟုတ်ပါ၊ တည်နေရာမှန်ကန်မှုကိုလည်း အာမ မခံနိုင်ပါ။ ယာဉ်မောင်းနှင်နေစဉ် Android Auto အတွက်ရည်ရွယ်ထားခြင်းမဟုတ်သည့် မိုဘိုင်းစက်ပစ္စည်း ကိုမကိုင်တွယ်ပါနှင့် သို့မဟုတ် အက်ပ်များကို အသုံးမပြုပါနှင့်။ိ"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 87b2b54..377642b 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Bare\nPrioritet"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Bare\nalarmer"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Alle\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Lader (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Lader raskt (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lader sakte (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startside"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nylige"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tilbake"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Vis «Ikke forstyrr» i volumkontrollene"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Tillat full kontroll over «Ikke forstyrr» i volumdialogen."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volum og «Ikke forstyrr»"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Åpne «Ikke forstyrr» med volum ned-knappen"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Lukk «Ikke forstyrr» med volum opp-knappen"</string>
+    <string name="battery" msgid="7498329822413202973">"Batteri"</string>
+    <string name="clock" msgid="7416090374234785905">"Klokke"</string>
+    <string name="headset" msgid="4534219457597457353">"Hodetelefoner"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Øretelefoner er tilkoblet"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Hodetelefoner er tilkoblet"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Vis eller skjul ikoner i statusfeltet."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings_car.xml b/packages/SystemUI/res/values-nb/strings_car.xml
new file mode 100644
index 0000000..421420e
--- /dev/null
+++ b/packages/SystemUI/res/values-nb/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Kjør forsiktig"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Ha full oversikt over kjøreforhold, og følg alltid gjeldende lov og rett. Veibeskrivelser kan være unøyaktige, ufullstendige, farlige, upassende, forbudte eller de kan involvere kjøring på administrative områder. Bedriftsinformasjon kan også være unøyaktig eller ufullstendig. Data er ikke i sanntid, og posisjonsnøyaktighet kan ikke garanteres. Ikke bruk mobilenheten din eller apper som ikke er ment for Android Auto, mens du kjører."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index a56a701..2a15c87 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"प्राथमिकता \nमात्र"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"अलार्महरू \nमात्र"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"सबै"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"सबै\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"चार्ज हुँदै (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण भएसम्म)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"छिटो चार्ज हुँदै (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण नभएसम्म)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"बिस्तारै चार्ज हुँदै (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण नभएसम्म)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"गृह"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हालैका"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"पछाडि"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"भोल्युममा बाधा नपुर्याउनुहोस् देखाउनुहोस्"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"भोल्युमको संवादमा बाधा नपुर्याउनुहोस् को पूर्ण नियन्त्रणलाई अनुमति दिनुहोस्"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"भोल्युम र बाधा नपुर्याउनुहोस्"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"भोल्युम कम गर्नेमा बाधा नपुर्याउनुहोस् प्रविष्ट गर्नुहोस्"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"भोल्युम बढाउनेमा बाधा नपुर्याउनुहोस् प्रविष्ट गर्नुहोस्"</string>
+    <string name="battery" msgid="7498329822413202973">"ब्याट्री"</string>
+    <string name="clock" msgid="7416090374234785905">"घडी"</string>
+    <string name="headset" msgid="4534219457597457353">"हेडसेट"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"हेडफोनहरू जडान गरियो"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"हेडसेट जडान गरियो"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"वस्तुस्थिति पट्टीमा देखाइनको लागि आइकनहरू सक्रिय वा निष्क्रिय गर्नुहोस्।"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings_car.xml b/packages/SystemUI/res/values-ne-rNP/strings_car.xml
new file mode 100644
index 0000000..1a4f8ef9
--- /dev/null
+++ b/packages/SystemUI/res/values-ne-rNP/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"सुरक्षित तरिकाले सवारी चलाउनुहोस्"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ड्राइभिङ सर्तहरूका बारे पूर्ण सजग रहनुहोस् र जहिले पनि लागू हुने नियमहरूको पालना गर्नुहोस्। दिशा निर्देशनहरू अशुद्ध, अपूर्ण, खतरनाक, अनुपयुक्त, निषेधित वा प्रशासनिक क्षेत्र पार गर्ने हुन सक्छ। व्यवसायिक जानकारी अशुद्ध वा अपूर्ण पनि हुन सक्छ। डेटा वास्तविक समयको हुँदैन र स्थान सटीकताको ग्यारेन्टी गर्न सकिँदैन। आफ्नो मोबाइल यन्त्र ह्याण्डल गर्ने वा सवारी चलाएको बेलामा Android स्वतःको लागि लक्षित नगरिएका अनुप्रयोगहरूको प्रयोग गर्ने नगर्नुहोस्।"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index a811db3..3e91b5c 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume en \'Niet storen\'"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"\'Niet storen\' activeren bij volume omlaag"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"\'Niet storen\' afsluiten bij volume omhoog"</string>
+    <string name="battery" msgid="7498329822413202973">"Accu"</string>
+    <string name="clock" msgid="7416090374234785905">"Klok"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Hoofdtelefoon aangesloten"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset aangesloten"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"De weergave van pictogrammen in de statusbalk in- of uitschakelen."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings_car.xml b/packages/SystemUI/res/values-nl/strings_car.xml
new file mode 100644
index 0000000..be66e01
--- /dev/null
+++ b/packages/SystemUI/res/values-nl/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Rijd veilig"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Blijf je volledig bewust van de rijomstandigheden en houd je altijd aan de wet. Aanwijzingen kunnen onnauwkeurig, onvolledig, gevaarlijk, ongeschikt of verboden zijn of het doorkruisen van overheidszones vereisen. Bedrijfsinformatie kan ook onnauwkeurg of onvolledig zijn. De gegevens worden niet in realtime verstrekt en de nauwkeurigheid van een locatie kan niet worden gegarandeerd. Bedien tijdens het rijden je mobiele apparaat niet en gebruik geen apps die niet bedoeld zijn voor Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index f3c85eb..1c98369 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ਵੌਲਯੂਮ ਅਤੇ ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"ਵੌਲਯੂਮ ਘੱਟ ਹੋਣ \'ਤੇ ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"ਵੌਲਯੂਮ ਉੱਚੀ ਹੋਣ \'ਤੇ ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
+    <string name="battery" msgid="7498329822413202973">"ਬੈਟਰੀ"</string>
+    <string name="clock" msgid="7416090374234785905">"ਘੜੀ"</string>
+    <string name="headset" msgid="4534219457597457353">"ਹੈੱਡਸੈੱਟ"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ਹੈੱਡਫੋਨਾਂ ਨੂੰ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ਹੈੱਡਸੈੱਟ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"ਚਿੰਨ੍ਹਾਂ ਦੇ ਸਥਿਤੀ ਪੱਟੀ ਵਿੱਚ ਵਿਖਾਏ ਜਾਣ ਨੂੰ ਯੋਗ ਜਾਂ ਅਯੋਗ ਬਣਾਓ।"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings_car.xml b/packages/SystemUI/res/values-pa-rIN/strings_car.xml
new file mode 100644
index 0000000..ac38625d
--- /dev/null
+++ b/packages/SystemUI/res/values-pa-rIN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਗੱਡੀ ਚਲਾਓ"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"ਗੱਡੀ ਚਲਾਉਣ ਦੇ ਹਾਲਾਤਾਂ ਤੋਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਜਾਣੂ ਰਹੋ ਅਤੇ ਸਦਾ ਲਾਗੂ ਕਾਨੂੰਨਾਂ ਦੀ ਪਾਲਣਾ ਕਰੋ। ਦਿਸ਼ਾਵਾਂ ਗਲਤ, ਅਧੂਰੀਆਂ, ਖ਼ਤਰਨਾਕ, ਢੁੱਕਵੀਆਂ ਨਹੀਂ, ਪ੍ਰਤਿਬੰਧਿਤ ਹੋ ਸਕਦੀਆਂ ਹਨ ਜਾਂ ਪ੍ਰਸ਼ਾਸਕੀ ਖੇਤਰਾਂ ਵਿੱਚੋਂ ਲੰਘਣਾ ਸ਼ਾਮਲ ਹੋ ਸਕਦਾ ਹੈ। ਵਪਾਰਕ ਜਾਣਕਾਰੀ ਵੀ ਗਲਤ ਜਾਂ ਅਧੂਰੀ ਹੋ ਸਕਦੀ ਹੈ। ਡੈਟਾ ਰੀਅਲ-ਟਾਈਮ ਨਹੀਂ ਹੈ ਅਤੇ ਟਿਕਾਣਾ ਸਟੀਕਤਾ ਗਾਰੰਟੀਸ਼ੁਦਾ ਨਹੀਂ ਹੋ ਸਕਦੀ ਹੈ। ਗੱਡੀ ਚਲਾਉਣ ਦੌਰਾਨ ਆਪਣੀ ਮੋਬਾਈਲ ਡੀਵਾਈਸ ਜਾਂ ਉਹਨਾਂ ਐਪਾਂ ਦੀ ਵਰਤੋਂ ਨਾ ਕਰੋ ਜੋ ਕਿ Android Auto ਲਈ ਨਹੀਂ ਬਣੀਆਂ ਹਨ।"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 4224730..fde806b 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -334,8 +334,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Tylko\npriorytetowe"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Tylko\nalarmy"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Wszystkie"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Wszystkie\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Ładuje się (pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Szybkie ładowanie (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do końca)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Wolne ładowanie (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do końca)"</string>
@@ -485,14 +484,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekran główny"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Ostatnie"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Wstecz"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Pokaż panel Nie przeszkadzać w oknie sterowania głośnością"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Pokaż cały panel Nie przeszkadzać w oknie sterowania głośnością."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Głośność i tryb Nie przeszkadzać"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Włącz tryb Nie przeszkadzać przy zmniejszaniu głośności"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Wyłącz tryb Nie przeszkadzać przy zwiększaniu głośności"</string>
+    <string name="battery" msgid="7498329822413202973">"Bateria"</string>
+    <string name="clock" msgid="7416090374234785905">"Zegar"</string>
+    <string name="headset" msgid="4534219457597457353">"Zestaw słuchawkowy"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Słuchawki są podłączone"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Zestaw słuchawkowy jest podłączony"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Włącz lub wyłącz wyświetlanie ikon na pasku stanu."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings_car.xml b/packages/SystemUI/res/values-pl/strings_car.xml
new file mode 100644
index 0000000..d6e02d6
--- /dev/null
+++ b/packages/SystemUI/res/values-pl/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Jedź bezpiecznie"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uważnie obserwuj warunki na drodze i zawsze przestrzegaj obowiązującego prawa. Wskazówki mogą być niedokładne, niekompletne, niebezpieczne, nieprzydatne lub niezgodne z prawem, mogą też obejmować przekraczanie obszarów administracyjnych. Informacje o firmach również mogą być niedokładne lub niekompletne. Dane nie są podawane w czasie rzeczywistym. Nie ma gwarancji, że dane o lokalizacji są dokładne. Podczas prowadzenia samochodu nie obsługuj urządzenia mobilnego ani nie używaj aplikacji nieprzeznaczonych na Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index d81fd8a..38a6b79 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Somente\nprioridade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Somente\nalarmes"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Tudo"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Todas\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até concluir)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Carregando rapidamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Carregando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Voltar"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Mostrar \"Não perturbe\" nas opções de volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Permitir controle total do recurso \"Não perturbe\" na caixa de diálogo de volume."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume e \"Não perturbe\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Entre no modo \"Não perturbe\" abaixando o volume"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Saia do modo \"Não perturbe\" aumentando o volume"</string>
+    <string name="battery" msgid="7498329822413202973">"Bateria"</string>
+    <string name="clock" msgid="7416090374234785905">"Relógio"</string>
+    <string name="headset" msgid="4534219457597457353">"Fone de ouvido"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Fones de ouvido conectados"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Fone de ouvido conectado"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Ativar ou desativar a exibição de ícones na barra de status."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_car.xml b/packages/SystemUI/res/values-pt-rBR/strings_car.xml
new file mode 100644
index 0000000..072f614
--- /dev/null
+++ b/packages/SystemUI/res/values-pt-rBR/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Dirija com segurança"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mantenha-se atento às condições de direção e sempre obedeça às leis aplicáveis. As instruções podem ser imprecisas, incompletas, perigosas, inadequadas, proibidas ou envolver o cruzamento de áreas administrativas. As informações comerciais também podem ser imprecisas ou incompletas. Os dados não são exibidos em tempo real, e a precisão da localização não pode ser garantida. Enquanto dirige, não manuseie seu dispositivo móvel nem use apps que não tenham sido criados para o Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index bfaf659..7e66dcf 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Apenas\nprioridade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Apenas\nalarmes"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Tudo"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Todas\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"A carregar (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"A carregar rapid. (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"A carregar lentam. (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Página inicial"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Anterior"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Mostrar Não incomodar no volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Permitir o controlo total de Não incomodar na caixa de diálogo do volume."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume e Não incomodar"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Ativar Não incomodar ao diminuir o volume"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Desativar Não incomodar ao aumentar o volume"</string>
+    <string name="battery" msgid="7498329822413202973">"Bateria"</string>
+    <string name="clock" msgid="7416090374234785905">"Relógio"</string>
+    <string name="headset" msgid="4534219457597457353">"Ausc. com microfone integrado"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Auscultadores ligados"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Auscultadores com microfone integrado ligados"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Ativar ou desativar a apresentação de ícones na barra de estado."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_car.xml b/packages/SystemUI/res/values-pt-rPT/strings_car.xml
new file mode 100644
index 0000000..e53774b7
--- /dev/null
+++ b/packages/SystemUI/res/values-pt-rPT/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduza com segurança"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mantenha-se completamente atento às condições de condução e respeite sempre as leis aplicáveis. As direções podem ser imprecisas, incompletas, perigosas, inadequadas, proibidas ou envolver a travessia de zonas administrativas. Os dados das empresas também podem ser imprecisos ou incompletos. Os dados não são fornecidos em tempo real e não é possível garantir a precisão da localização. Não manuseie o dispositivo móvel nem utilize aplicações não destinadas ao Android Auto durante a condução."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
index 5b4567e..e0ca35d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
@@ -24,5 +24,5 @@
     <string name="pip_play" msgid="674145557658227044">"Reproduzir"</string>
     <string name="pip_pause" msgid="8412075640017218862">"Interromper"</string>
     <string name="pip_cancel" msgid="5173898361050559462">"Cancelar"</string>
-    <string name="pip_hold_home" msgid="883546189749854120">"Prima sem soltar HOME para controlar o PIP"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Prima sem soltar a tecla HOME para controlar o PIP"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index d81fd8a..38a6b79 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Somente\nprioridade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Somente\nalarmes"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Tudo"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Todas\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até concluir)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Carregando rapidamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Carregando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Voltar"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Mostrar \"Não perturbe\" nas opções de volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Permitir controle total do recurso \"Não perturbe\" na caixa de diálogo de volume."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume e \"Não perturbe\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Entre no modo \"Não perturbe\" abaixando o volume"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Saia do modo \"Não perturbe\" aumentando o volume"</string>
+    <string name="battery" msgid="7498329822413202973">"Bateria"</string>
+    <string name="clock" msgid="7416090374234785905">"Relógio"</string>
+    <string name="headset" msgid="4534219457597457353">"Fone de ouvido"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Fones de ouvido conectados"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Fone de ouvido conectado"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Ativar ou desativar a exibição de ícones na barra de status."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings_car.xml b/packages/SystemUI/res/values-pt/strings_car.xml
new file mode 100644
index 0000000..072f614
--- /dev/null
+++ b/packages/SystemUI/res/values-pt/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Dirija com segurança"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Mantenha-se atento às condições de direção e sempre obedeça às leis aplicáveis. As instruções podem ser imprecisas, incompletas, perigosas, inadequadas, proibidas ou envolver o cruzamento de áreas administrativas. As informações comerciais também podem ser imprecisas ou incompletas. Os dados não são exibidos em tempo real, e a precisão da localização não pode ser garantida. Enquanto dirige, não manuseie seu dispositivo móvel nem use apps que não tenham sido criados para o Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 484a1b8..e045fc8 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -56,7 +56,7 @@
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Permiteți aplicației <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze accesoriul USB?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui dispozitiv USB?"</string>
     <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="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="always_use_device" msgid="1450287437017315906">"Utilizaţi în mod prestabilit pt. acest dispoz. USB"</string>
@@ -333,8 +333,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Numai\ncu prioritate"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Numai\nalarme"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Toate"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Toate\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Se încarcă (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Se încarcă rapid (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Se încarcă lent (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
@@ -484,14 +483,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ecran de pornire"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recente"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Înapoi"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Afișați opțiunile pentru Nu deranjați în dialogul de volum"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Permiteți controlul complet al modului Nu deranjați din dialogul pentru volum."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volumul și Nu deranjați"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Accesați Nu deranjați la reducerea volumului"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Ieșiți din Nu deranjați la creșterea volumului"</string>
+    <string name="battery" msgid="7498329822413202973">"Baterie"</string>
+    <string name="clock" msgid="7416090374234785905">"Ceas"</string>
+    <string name="headset" msgid="4534219457597457353">"Set căști-microfon"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Căștile sunt conectate"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Setul căști-microfon este conectat"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Activați sau dezactivați afișarea pictogramelor în bara de stare."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings_car.xml b/packages/SystemUI/res/values-ro/strings_car.xml
new file mode 100644
index 0000000..54d8585
--- /dev/null
+++ b/packages/SystemUI/res/values-ro/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Conduceți atent"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Aflați mereu condițiile de trafic și respectați întotdeauna legislația aplicabilă. Indicațiile de orientare pot fi inexacte, incomplete, periculoase, neadecvate, interzise sau pot implica trecerea prin zone administrative. Informațiile despre companii pot fi, de asemenea, inexacte sau incomplete. Datele nu sunt în timp real și nu se poate garanta exactitatea locației. Nu manipulați dispozitivul mobil și nu folosiți aplicații neconcepute pentru Android Auto când sunteți la volan."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 0876366..d9f7a9b 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -334,8 +334,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Только\nважные"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Только\nбудильник"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Все"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Все\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Зарядка батареи (осталось <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Быстрая зарядка (осталось <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Медленная зарядка (осталось <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -485,14 +484,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Главный экран"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавние"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Показать панель \"Не беспокоить\" в окне регулировки звука"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Позволяет управлять режимом \"Не беспокоить\" в окне регулировки громкости."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Регулировка громкости и режим \"Не беспокоить\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Включать режим \"Не беспокоить\" при уменьшении громкости"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Отключать режим \"Не беспокоить\" при увеличении громкости"</string>
+    <string name="battery" msgid="7498329822413202973">"Батарея"</string>
+    <string name="clock" msgid="7416090374234785905">"Часы"</string>
+    <string name="headset" msgid="4534219457597457353">"Гарнитура"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Наушники подключены"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Гарнитура подключена"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Включение и отключение показа значков в строке состояния"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings_car.xml b/packages/SystemUI/res/values-ru/strings_car.xml
new file mode 100644
index 0000000..cbdb8d7
--- /dev/null
+++ b/packages/SystemUI/res/values-ru/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Безопасность движения"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Всегда учитывайте дорожную обстановку и соблюдайте правила. Маршруты могут быть неточными, неполными, проходить по опасным, неподходящим или запрещенным для движения участкам или пересекать границы. Сведения об организациях также могут быть неточными и неполными. Данные не обновляются в режиме реального времени, и точность определения местоположения не гарантируется. Не пользуйтесь мобильным устройством и не используйте приложения, не предназначенные для Android Auto, управляя автомобилем."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 4520aef..69514d4 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ප්‍රමුඛතා\nපමණි"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ඇඟවීම්\nපමණි"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"සියලු"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"සියලු\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ආරෝපණය වෙමින් (සම්පුර්ණ වන තෙක් <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"ඉක්මනින් ආරෝපණය වෙමින් (සම්පුර්ණ වන තෙක් <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"සෙමින් ආරෝපණය වෙමින් (සම්පුර්ණ වන තෙක් <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"මුල් පිටුව"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"මෑත"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ආපසු"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"හඩ පරිමාව තුළ බාධා නොකරන්න පුවරුව පෙන්වන්න"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"හඬ පරිමා සංවාදය තුළ බාධා නොකරන්න පුවරුවට පූර්ණ පාලනය ඉඩ දෙන්න."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"හඬ පරිමාව සහ බාධා නොකරන්න"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"හඬ පරිමාව අඩු කරන්න මත බාධා නොකරන්න වෙත ඇතුළු වන්න"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"හඬ පරිමාව වැඩි කරන්න මත බාධා නොකරන්න වෙතින් ඉවත් වන්න"</string>
+    <string name="battery" msgid="7498329822413202973">"බැටරිය"</string>
+    <string name="clock" msgid="7416090374234785905">"ඔරලෝසුව"</string>
+    <string name="headset" msgid="4534219457597457353">"හෙඩ්සෙට්"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"හෙඩ්ෆෝන් සම්බන්ධ කළ"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"හෙඩ්සෙට් සම්බන්ධ කළ"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"තත්ත්ව තීරුව මත අයිකන පෙන්වීම සබල හෝ අබල කරන්න."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings_car.xml b/packages/SystemUI/res/values-si-rLK/strings_car.xml
new file mode 100644
index 0000000..549e89b
--- /dev/null
+++ b/packages/SystemUI/res/values-si-rLK/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ආරක්ෂිතව රිය පදවන්න"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"රිය පැදවීම් තත්ත්වයන් ගැන පූර්ණ අවධානයෙන් සිටින්න, සැම විටම අදාළ සියලු නීතිවලට ගරු කරන්න. මග පෙන්වීම් නිවැරදි නොවීමට, අසම්පූර්ණ වීමට, භයානක වීමට, නුසුදුසු වීමට, තහනම් ඒවා වීමට, හෝ පරිපාලන ප්‍රදේශ තරණයට අදාළ ඒවා වීමට හැකිය. දත්ත තථ්‍ය කාල නොවීමට හැකි අතර, ස්ථාන නිරවද්‍යතාව සහතික කළ නොහැකිය. රිය පදවන අතරතුර ඔබේ ජංගම උපාංගය භාවිත කිරීම හෝ Android Auto සඳහා නිපදවා නැති යෙදුම් භාවිත කිරීම නොකරන්න."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings_tv.xml b/packages/SystemUI/res/values-si-rLK/strings_tv.xml
index fe51cc8..b3beef3 100644
--- a/packages/SystemUI/res/values-si-rLK/strings_tv.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings_tv.xml
@@ -20,7 +20,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="pip_exit" msgid="6423523158795119008">"PIP වසන්න"</string>
-    <string name="pip_fullscreen" msgid="8604643018538487816">"පූර්ණ තිරය"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"සම්පූර්ණ තිරය"</string>
     <string name="pip_play" msgid="674145557658227044">"ධාවනය කරන්න"</string>
     <string name="pip_pause" msgid="8412075640017218862">"විරාමය"</string>
     <string name="pip_cancel" msgid="5173898361050559462">"අවලංගු කරන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 7458212..9ef3d47 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -334,8 +334,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Iba\nprioritné"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Iba\nbudíky"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Všetky"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Všetky\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nabíja sa (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Nabíja sa rýchlo (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Nabíja sa pomaly (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -485,14 +484,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Domovská stránka"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedávne"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Späť"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Zobrazovať panel Nerušiť v dialógu Hlasitosť"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Umožňuje povoliť úplné ovládanie režimu nerušiť v dialógu Hlasitosť."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Hlasitosť a režim Nerušiť"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Pri znížení hlasitosti prejsť do režimu Nerušiť"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Pri zvýšení hlasitosti ukončiť režim Nerušiť"</string>
+    <string name="battery" msgid="7498329822413202973">"Batéria"</string>
+    <string name="clock" msgid="7416090374234785905">"Hodiny"</string>
+    <string name="headset" msgid="4534219457597457353">"Náhlavná súprava"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Slúchadlá pripojené"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Náhlavná súprava pripojená"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Umožňuje aktivovať alebo deaktivovať zobrazenie ikon v stavovom riadku."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings_car.xml b/packages/SystemUI/res/values-sk/strings_car.xml
new file mode 100644
index 0000000..bd9410d
--- /dev/null
+++ b/packages/SystemUI/res/values-sk/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Jazdite bezpečne"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Zachovajte si úplný prehľad o jazdných podmienkach a vždy dodržiavajte príslušné zákony. Trasy môžu byť nepresné, neúplné, nebezpečné, nevhodné, zakázané alebo môžu zahŕňať cestu cez rôzne správne oblasti. Obchodné informácie môžu byť tiež nepresné alebo neúplné. Údaje nie sú aktualizované v reálnom čase a presnosť polohy nemôžeme zaručiť. Počas jazdy nemanipulujte s mobilným zariadením ani nepoužívajte aplikácie, ktoré nie sú určené pre funkciu Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 59037a8..9fda17b 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -334,8 +334,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Samo\nprednostno"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Samo\nalarmi"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Vse"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Vse\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Hitro polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Počasno polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
@@ -485,14 +484,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Začetni zaslon"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazaj"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Pokaži način »ne moti« v nadzoru glasnosti"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Omogoča popoln nadzor načina »ne moti« v pogovornem oknu za glasnost."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Nadzor glasnosti in način »ne moti«"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Odpiranje načina »ne moti« pri zmanjšanju glasnosti"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Zapustitev načina »ne moti« pri povečanju glasnosti"</string>
+    <string name="battery" msgid="7498329822413202973">"Akumulator"</string>
+    <string name="clock" msgid="7416090374234785905">"Ura"</string>
+    <string name="headset" msgid="4534219457597457353">"Slušalke z mikrofonom"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Slušalke priključene"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Slušalke z mikrofonom priključene"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Omogoči ali onemogoči prikaz ikon v vrstici stanja."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings_car.xml b/packages/SystemUI/res/values-sl/strings_car.xml
new file mode 100644
index 0000000..0102799
--- /dev/null
+++ b/packages/SystemUI/res/values-sl/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Varna vožnja"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Bodite pozorni na vozne razmere in vselej upoštevajte veljavno zakonodajo. Navodila za pot so morda nenatančna, nepopolna, nevarna, neprimerna ali prepovedana oziroma vključujejo prečkanje upravnih območij. Prav tako nenatančni ali nepopolni so lahko podatki o podjetjih. Podatki niso sprotni in natančnosti lociranja ni mogoče zagotoviti. Med vožnjo ne uporabljajte mobilne naprave ali aplikacij, ki niso namenjene za Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 7dcad4e..a43ac7e 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volumi dhe \"Mos shqetëso\""</string>
     <string name="volume_down_silent" msgid="66962568467719591">"Vendos \"Mos shqetëso\" me volumin poshtë"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"Dil nga \"Mos shqetëso\" me volumin lart"</string>
+    <string name="battery" msgid="7498329822413202973">"Bateria"</string>
+    <string name="clock" msgid="7416090374234785905">"Ora"</string>
+    <string name="headset" msgid="4534219457597457353">"Kufjet me mikrofon"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Kufjet u lidhën"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Kufjet me mikrofon u lidhën"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Aktivizo ose çaktivizo shfaqjen e ikonave në shiritin e statusit."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings_car.xml b/packages/SystemUI/res/values-sq-rAL/strings_car.xml
new file mode 100644
index 0000000..2e63877
--- /dev/null
+++ b/packages/SystemUI/res/values-sq-rAL/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Drejtoje makinën në mënyrë të sigurt"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Ji plotësisht i vetëdijshëm për kushtet e lëvizjes me makinë dhe respekto gjithmonë ligjet përkatëse. Udhëzimet mund të jenë të pasakta, jo të plota, të rrezikshme, të papërshtatshme, të ndaluara ose mund të përfshijnë kalimin në zona administrative. Informacionet e biznesit mund të jenë po ashtu të pasakta ose jo të plota. Të dhënat nuk janë në kohë reale dhe saktësia e vendndodhjes nuk mund të garantohet. Gjatë drejtimit të makinës mos e përdor pajisjen celulare ose mos përdor aplikacionet që nuk janë të planifikuara për Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index d6a4359..765df27 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -333,8 +333,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Само\nприорит. прекиди"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Само\nаларми"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Све"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Сви\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Пуњење (пун је за <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Брзо се пуни (напуниће се за <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Споро се пуни (напуниће се за <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -484,14 +483,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетни"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавни садржај"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Прикажи подешавање Не узнемиравај у дијалогу за јачину звука"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Дозвољава потпуну контролу подешавања Не узнемиравај у дијалогу за јачину звука."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Јачина звука и Не узнемиравај"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Уђи у режим Не узнемиравај када је звук утишан"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Изађи из режима Не узнемиравај када је звук појачан"</string>
+    <string name="battery" msgid="7498329822413202973">"Батерија"</string>
+    <string name="clock" msgid="7416090374234785905">"Сат"</string>
+    <string name="headset" msgid="4534219457597457353">"Наглавне слушалице"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Слушалице су повезане"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Наглавне слушалице су повезане"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Омогућите или онемогућите приказивање икона на статусној траци."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings_car.xml b/packages/SystemUI/res/values-sr/strings_car.xml
new file mode 100644
index 0000000..7f99120
--- /dev/null
+++ b/packages/SystemUI/res/values-sr/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Возите безбедно"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Увек водите рачуна о условима вожње и увек поштујте примењиве законе. Упутства могу да буду нетачна, непотпуна, опасна, неприкладна или забрањена, односно да подразумевају прелазак између административних области. И подаци о предузећу могу да буду нетачни или непотпуни. Подаци не настају у реалном времену и не можемо да гарантујемо прецизност локације. Немојте да употребљавате мобилни уређај нити да користите апликације које нису намењене за Android Auto током вожње."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 4d8a0e3..c76d1d3 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Endast\nprioriterade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Endast\nalarm"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Alla"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Alla\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laddar (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tills batteriet är fulladdat)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Laddas snabbt (batteriet fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Laddas sakta (batteriet fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startsida"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Senaste"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tillbaka"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Visa Stör ej i volymkontrollen"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Tillåt full kontroll över Stör ej i volymkontrollen"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volym och Stör ej"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Aktivera Stör ej när volymen sänks"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Inaktivera Stör ej när volymen höjs"</string>
+    <string name="battery" msgid="7498329822413202973">"Batteri"</string>
+    <string name="clock" msgid="7416090374234785905">"Klocka"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Hörlurar anslutna"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Headset anslutet"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Visa eller dölj ikoner i statusfältet."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings_car.xml b/packages/SystemUI/res/values-sv/strings_car.xml
new file mode 100644
index 0000000..0c03fb6
--- /dev/null
+++ b/packages/SystemUI/res/values-sv/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Kör försiktigt"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Håll koll på trafik- och körförhållanden och följ gällande lagar. Det kan hända att vägbeskrivningen inte stämmer, att den är ofullständig, farlig, olämplig, förbjuden eller att den innebär att du måste korsa en administrativ enhet. Det kan även hända att företagsuppgifter är felaktiga eller ofullständiga. Uppgifter visas inte i realtid och det går inte att garantera att platsen är korrekt. Hantera inte din mobila enhet och använd inte appar som inte är ämnade för Android Auto medan du kör."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 97b1a3d..031e2b1 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Kipaumbele\npekee"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Kengele\npekee"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Zote"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Zote\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Inachaji (Imebakisha <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ijae)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Inachaji kwa kasi (itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Inachaji pole pole (itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Mwanzo"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Zilizotumika majuzi"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nyuma"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Onyesha hali ya usinisumbue katika sauti"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Ruhusu udhibiti kamili wa hali ya usinisumbue katika kidirisha cha sauti."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Sauti na Usinisumbue"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Weka hali ya usinisumbue sauti inapopunguzwa"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Ondoa hali ya usinisumbue sauti inapoongezwa"</string>
+    <string name="battery" msgid="7498329822413202973">"Betri"</string>
+    <string name="clock" msgid="7416090374234785905">"Saa"</string>
+    <string name="headset" msgid="4534219457597457353">"Vifaa vya sauti"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Imeunganisha spika za masikioni"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Imeunganisha vifaa vya sauti"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Washa au uzime aikoni ili zisionekane kwenye sehemu ya arifa"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings_car.xml b/packages/SystemUI/res/values-sw/strings_car.xml
new file mode 100644
index 0000000..e4bb25c
--- /dev/null
+++ b/packages/SystemUI/res/values-sw/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Endesha gari kwa usalama"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Jifahamishe kikamilifu kuhusu masharti ya kuendesha gari na utii kila wakati sheria zilizopo. Huenda maelekezo yasiwe sahihi, hayajakamilika, ni hatari, hayafai, hayaruhusiwi au yanahusisha kuvuka maeneo ya kiutawala. Huenda pia maelezo ya biashara yasiwe sahihi au hayajakamilika. Data si ya wakati halisi na hatuwezi kukupa hakikisho kuhusu usahihi wa mahali. Usitumie kifaa chako cha mkononi au programu zisizo za Android Auto wakati unapoendesha gari."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 6efa264..b64ef74 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"முன்னுரிமைகள்\nமட்டும்"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"அலாரங்கள்\nமட்டும்"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"எல்லாம்"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"எல்லாம்\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"சார்ஜாகிறது (முழு சார்ஜிற்கு <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ஆகும்)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"வேகமாக சார்ஜாகிறது (முழு சார்ஜிற்கு: <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"மெதுவாக சார்ஜாகிறது (முழு சார்ஜிற்கு: <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"முகப்பு"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"சமீபத்தியவை"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"முந்தையது"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"ஒலி உரையாடலில் தொந்தரவு செய்ய வேண்டாம் என்பதைக் காட்டு"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"ஒலி உரையாடலில் தொந்தரவு செய்ய வேண்டாம் என்பதன் முழுக் கட்டுப்பாட்டையும் அனுமதி."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ஒலி மற்றும் தொந்தரவு செய்ய வேண்டாம்"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"ஒலியைக் குறைக்கும் போது தொந்தரவு செய்ய வேண்டாம் என்பதை இயக்கு"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ஒலியைக் கூட்டும் போது தொந்தரவு செய்ய வேண்டாம் என்பதை முடக்கு"</string>
+    <string name="battery" msgid="7498329822413202973">"பேட்டரி"</string>
+    <string name="clock" msgid="7416090374234785905">"கடிகாரம்"</string>
+    <string name="headset" msgid="4534219457597457353">"ஹெட்செட்"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ஹெட்ஃபோன்கள் இணைக்கப்பட்டன"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ஹெட்செட் இணைக்கப்பட்டது"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"நிலைப் பட்டியில் ஐகான்களைக் காட்டுவதை இயக்கும் அல்லது முடக்கும்."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings_car.xml b/packages/SystemUI/res/values-ta-rIN/strings_car.xml
new file mode 100644
index 0000000..b40ba76
--- /dev/null
+++ b/packages/SystemUI/res/values-ta-rIN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"பாதுகாப்பாக ஓட்டவும்"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"வாகனம் ஓட்டுவதற்கான சூழ்நிலைகளை முழுவதுமாகத் தெரிந்து வைத்திருக்கவும் மற்றும் பொருந்தும் விதிகளை எப்போதும் பின்பற்றவும். வழிகள் துல்லியமற்றதாக, முழுமையற்றதாக, ஆபத்துக்குரியதாக, பொருத்தமில்லாததாக, தடைசெய்யப்பட்டதாக அல்லது அரசின் கட்டுப்பாட்டில் உள்ள எல்லைகளைக் கடப்பதாக இருக்கலாம். வணிகத் தகவலும் துல்லியமற்றதாக அல்லது முழுமையற்றதாக இருக்கலாம். தரவு நிகழ்நேர அடிப்படையிலானது அல்ல மற்றும் இருப்பிடத் துல்லியத்திற்கு உத்தரவாதம் வழங்க முடியாது. வாகனம் ஓட்டும் போது மொபைல் சாதனத்தையோ அல்லது Android Auto மூலம் கட்டுப்படுத்த முடியாத பயன்பாடுகளையோ பயன்படுத்த வேண்டாம்."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 2d30739..1e953d8 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -487,4 +487,16 @@
     <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"వాల్యూమ్ మరియు అంతరాయం కలిగించవద్దు"</string>
     <string name="volume_down_silent" msgid="66962568467719591">"వాల్యూమ్ తగ్గిస్తే అంతరాయం కలిగించవద్దులోకి ప్రవేశిస్తుంది"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"వాల్యూమ్ పెంచితే అంతరాయం కలిగించవద్దు నుండి నిష్క్రమిస్తుంది"</string>
+    <string name="battery" msgid="7498329822413202973">"బ్యాటరీ"</string>
+    <string name="clock" msgid="7416090374234785905">"గడియారం"</string>
+    <string name="headset" msgid="4534219457597457353">"హెడ్‌సెట్"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"హెడ్‌ఫోన్‌లు కనెక్ట్ చేయబడ్డాయి"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"హెడ్‌సెట్ కనెక్ట్ చేయబడింది"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"స్థితి పట్టీలో చిహ్నాలు ప్రదర్శించడాన్ని ప్రారంభించండి లేదా నిలిపివేయండి."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings_car.xml b/packages/SystemUI/res/values-te-rIN/strings_car.xml
new file mode 100644
index 0000000..6f60b3a
--- /dev/null
+++ b/packages/SystemUI/res/values-te-rIN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"సురక్షితంగా డ్రైవ్ చేయండి"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"డ్రైవింగ్ షరతులపై పూర్తి అవగాహనను కలిగి ఉండండి మరియు ఎల్లప్పుడూ వర్తించే చట్టాలకు అనుగుణంగా నడుచుకోండి. దిశలు నిర్దిష్టంగా ఉండకపోవచ్చు, అసంపూర్ణంగా ఉండవచ్చు, ప్రమాదకరంగా ఉండవచ్చు, అనుకూలంగా ఉండకపోవచ్చు, నిషేధించబడి ఉండవచ్చు లేదా పాలనా ప్రాంతాల మీదుగా వెళ్లే విధంగా ఉండవచ్చు. వ్యాపార సమాచారం కూడా నిర్దిష్టంగా లేదా సంపూర్ణంగా ఉండకపోవచ్చు. డేటా నిజ-సమయానికి సంబంధించినది కాదు మరియు స్థాన ఖచ్చితత్వానికి ఎలాంటి హామీ ఉండకపోవచ్చు. డ్రైవింగ్ చేస్తున్నప్పుడు మీ మొబైల్ పరికరాన్ని ఉపయోగించవద్దు లేదా Android Auto కోసం ఉద్దేశించబడని అనువర్తనాలను ఉపయోగించవద్దు."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 9ac8c16..c09b50f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"เฉพาะเรื่อง\nสำคัญ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"เฉพาะปลุก\nเท่านั้น"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"ทั้งหมด"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"ทั้งหมด\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"กำลังชาร์จ (อีก <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> เต็ม)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"กำลังชาร์จอย่างรวดเร็ว (อีก <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> จะเต็ม)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"กำลังชาร์จอย่างช้าๆ (อีก <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> จะเต็ม)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"หน้าแรก"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ล่าสุด"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"กลับ"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"แสดงโหมดห้ามรบกวนในระดับเสียง"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"อนุญาตให้ควบคุมโหมดห้ามรบกวนได้อย่างสมบูรณ์ในกล่องโต้ตอบระดับเสียง"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ระดับเสียงและโหมดห้ามรบกวน"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"เข้าสู่โหมดห้ามรบกวนเมื่อลดระดับเสียง"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ออกจากโหมดห้ามรบกวนเมื่อเพิ่มระดับเสียง"</string>
+    <string name="battery" msgid="7498329822413202973">"แบตเตอรี่"</string>
+    <string name="clock" msgid="7416090374234785905">"นาฬิกา"</string>
+    <string name="headset" msgid="4534219457597457353">"ชุดหูฟัง"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"เชื่อมต่อหูฟังแล้ว"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"เชื่อมต่อชุดหูฟังแล้ว"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"เปิดหรือปิดไอคอนจากการแสดงในแถบสถานะ"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings_car.xml b/packages/SystemUI/res/values-th/strings_car.xml
new file mode 100644
index 0000000..b40584a
--- /dev/null
+++ b/packages/SystemUI/res/values-th/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"ขับขี่อย่างปลอดภัย"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"มีสติรู้ตัวเต็มที่ในสภาพการขับขี่ต่างๆ เและปฏิบัติตามกฎหมายที่บังคับใช้เสมอ ทั้งนี้เส้นทางอาจไม่ถูกต้อง ไม่ครบถ้วน เป็นอันตราย ไม่เหมาะสม ห้ามใช้ หรือมีการข้ามเขตปกครอง นอกจากนี้ข้อมูลทางธุรกิจอาจไม่ถูกต้องหรือไม่สมบูรณ์ ข้อมูลไม่ใช่แบบเรียลไทม์ และไม่สามารถรับประกันความถูกต้องของตำแหน่ง อย่าใช้งานอุปกรณ์เคลื่อนที่หรือใช้แอปที่ไม่ได้ออกแบบมาสำหรับ Android Auto ขณะขับรถ"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 1d5a3b4..e76b40c 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priyoridad\nlang"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Mga alarm\nlang"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Lahat"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Lahat\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nagtsa-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang mapuno)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Mabilis mag-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang sa mapuno)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mabagal mag-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang sa mapuno)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Mga Kamakailang Ginamit"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Bumalik"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Ipakita ang huwag istorbohin sa volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Payagang ganap na makontrol ang huwag istorbohin sa dialog ng volume."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume at Huwag istorbohin"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Gamitin ang huwag istorbohin nang mahina ang volume"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Umalis sa huwag istorbohin nang malakas ang volume"</string>
+    <string name="battery" msgid="7498329822413202973">"Baterya"</string>
+    <string name="clock" msgid="7416090374234785905">"Orasan"</string>
+    <string name="headset" msgid="4534219457597457353">"Headset"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Nakakonekta ang mga headphone"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Nakakonekta ang headset"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"I-enable o i-disable ang pagpapakita sa mga icon sa status bar."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings_car.xml b/packages/SystemUI/res/values-tl/strings_car.xml
new file mode 100644
index 0000000..6bb04ab
--- /dev/null
+++ b/packages/SystemUI/res/values-tl/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Magmaneho nang ligtas"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Manatiling lubos na nakakaalam sa mga kundisyon sa pagmamaneho at palaging sumunod sa mga naaangkop na batas. Ang mga direksyon ay maaaring hindi tumpak, hindi kumpleto, mapanganib, hindi naaangkop, ipinagbabawal o kinasasangkutan ng pagtawid sa mga administratibong lugar. Maaari ding hindi tumpak o hindi kumpleto ang impormasyon ng negosyo. Hindi real-time ang data at hindi magagarantiya ang katumpakan ng lokasyon. Huwag gamitin ang iyong mobile device o gumamit ng mga app na hindi ginawa para sa Android Auto habang nagmamaneho."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 22108b5..a16adfd 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Yalnızca\nöncelik"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Yalnızca\nalarmlar"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Tümü"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Tümü\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Şarj oluyor (tamamen dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Hızlı şarj oluyor (tam dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Yavaş şarj oluyor (tam dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ana ekran"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Son çağrılar"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Geri"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Ses iletişim kutusunda rahatsız etmeyin modunu göster"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Ses iletişim kutusunda rahatsız etmeyin modunu tam olarak denetlemeye izin ver."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Ses ve Rahatsız etmeyin"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Ses kısıldığında rahatsız etmeyin moduna geç"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Ses açıldığında rahatsız etmeyin modundan çık"</string>
+    <string name="battery" msgid="7498329822413202973">"Pil"</string>
+    <string name="clock" msgid="7416090374234785905">"Saat"</string>
+    <string name="headset" msgid="4534219457597457353">"Mikrofonlu kulaklık"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Mikrofonlu kulaklık bağlı"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Mikrofonlu kulaklık bağlı"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Simgelerin durum çubuğunda görüntülenmesini etkinleştir veya devre dışı bırak"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings_car.xml b/packages/SystemUI/res/values-tr/strings_car.xml
new file mode 100644
index 0000000..72018e2
--- /dev/null
+++ b/packages/SystemUI/res/values-tr/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Güvenli bir şekilde sürün"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Sürüş koşullarına karşı dikkatli olun ve geçerli yasalara her zaman uyun. Yol tarifi yanlış, eksik, tehlikeli, uygunsuz, yasak olabilir veya idari bölgelerden geçişleri içerebilir. İşletme bilgileri de yanlış veya eksik olabilir. Veriler gerçek zamanlı değildir ve konum doğruluğu garanti edilemez. Sürüş sırasında mobil cihazınızı veya Android Auto için geliştirilmemiş uygulamaları kullanmayın."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 615a4c4..1c0e04e 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -334,8 +334,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Лише\nприорітетні"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Лише\nсигнали"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Усі"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Усі\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Заряджання (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до повного зарядження)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Швидке заряджання (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до повного заряду)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Повільне заряджання (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до повного заряду)"</string>
@@ -485,14 +484,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Головний екран"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Останні"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Показувати режим \"Не турбувати\" у вікні регулятора гучності"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Дозволити керувати режимом \"Не турбувати\" у вікні регулятора гучності."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Регулятор гучності та режим \"Не турбувати\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Вмикати режим \"Не турбувати\" під час зменшення гучності"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Вимикати режим \"Не турбувати\" під час збільшення гучності"</string>
+    <string name="battery" msgid="7498329822413202973">"Акумулятор"</string>
+    <string name="clock" msgid="7416090374234785905">"Годинник"</string>
+    <string name="headset" msgid="4534219457597457353">"Гарнітура"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Навушники під’єднано"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Гарнітуру під’єднано"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Показати або сховати значки в рядку стану."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings_car.xml b/packages/SystemUI/res/values-uk/strings_car.xml
new file mode 100644
index 0000000..4fda0ab
--- /dev/null
+++ b/packages/SystemUI/res/values-uk/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Будьте уважні за кермом"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Стежте умовами дорожнього руху та завжди дотримуйтеся відповідних законів. Маршрути можуть бути неточними, неповними, небезпечними, непридатними або перетинати межі адміністративних одиниць. Інформація про компанії також може бути неточною або неповною. Дані надаються не в реальному часі. Точність визначення місцезнаходжень не гарантується. Коли ви за кермом, не користуйтеся мобільним пристроєм або додатками, не призначеними для Android Auto."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index a789eec..67b52fd 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"صرف\nترجیحی"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"صرف\nالارمز"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"سبھی"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"تمام\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"چارج ہو رہا ہے (مکمل ہونے تک <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> باقی ہیں)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"تیزی سے چارج ہو رہا ہے (مکمل ہونے میں <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"آہستہ چارج ہو رہا ہے (مکمل ہونے میں <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ہوم"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"حالیہ"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"پیچھے"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"والیوم میں ڈسٹرب نہ کریں دکھائیں"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"والیوم ڈائیلاگ میں ڈسٹرب نہ کریں کے مکمل کنٹرول کی اجازت دیں۔"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"والیوم اور ڈسٹرب نہ کریں"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"کم والیوم پر \'ڈسٹرب نہ کریں\' میں داخل ہوں"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"زیادہ والیوم پر \'ڈسٹرب نہ کریں\' سے خارج ہوں"</string>
+    <string name="battery" msgid="7498329822413202973">"بیٹری"</string>
+    <string name="clock" msgid="7416090374234785905">"گھڑی"</string>
+    <string name="headset" msgid="4534219457597457353">"ہیڈ سیٹ"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"ہیڈ فونز منسلک ہیں"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"ہیڈ سیٹ منسلک ہے"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"اسٹیٹس بار میں دکھائے جانے کیلئے آئیکنز فعال یا غیر فعال کریں۔"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings_car.xml b/packages/SystemUI/res/values-ur-rPK/strings_car.xml
new file mode 100644
index 0000000..151ca09
--- /dev/null
+++ b/packages/SystemUI/res/values-ur-rPK/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"احتیاط سے گاڑی چلائیں"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"‏گاڑی چلاتے وقت اپنے گردونواح سے مکمل طور پر باخبر رہیں اور ہمیشہ قابل اطلاق قوانین کی پابندی کریں۔ ہدایات غلط، نامکمل، خطرناک، موزوں نہیں، ممنوع یا انتظامی علاقوں میں سے گزرنے کے متعلق ہو سکتی ہیں۔ کاروباری معلومات بھی غلط یا نامکمل ہو سکتی ہے۔ گاڑی چلاتے وقت اپنا موبائل آلہ یا وہ ایپس استعمال نہ کریں جو Android Auto کیلئے نہیں ہیں۔"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 4f32c34..dd91bad 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Faqat\nmuhimlar"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Faqat\nsignallar"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Barchasi"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Barcha\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Quvvat olmoqda (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>da to‘ladi)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Tez quvvat olmoqda (to‘lishiga <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> qoldi)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sekin quvvat olmoqda (to‘lishiga <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> qoldi)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Bosh ekran"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"So‘nggi ishlatilganlar"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Orqaga"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Ovoz boshqarish oynasida “Bezovta qilinmasin” panelini ko‘rsatish"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Ovoz balandligini boshqarish oynasida “Bezovta qilinmasin” rejimini to‘liq boshqarishga ruxsat beradi."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Ovoz balandligini boshqarish va “Bezovta qilinmasin” rejimi"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Ovozni pasaytirganda “Bezovta qilinmasin” rejimini yoqish"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Ovozni ko‘targanda “Bezovta qilinmasin” rejimini o‘chirish"</string>
+    <string name="battery" msgid="7498329822413202973">"Batareya"</string>
+    <string name="clock" msgid="7416090374234785905">"Soat"</string>
+    <string name="headset" msgid="4534219457597457353">"Audio moslama"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Quloqchinlar ulandi"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Audio moslama ulandi"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Holat qatorida begilarning ko‘rsatilishini yoqish yoki o‘chirish."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings_car.xml b/packages/SystemUI/res/values-uz-rUZ/strings_car.xml
new file mode 100644
index 0000000..610dc1f
--- /dev/null
+++ b/packages/SystemUI/res/values-uz-rUZ/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Xavfsiz haydash"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Harakat xavfsizligi va amaldagi qonunchilikka doim rioya qiling. Yo‘l ko‘rsatmalari noaniq, chala, xavfli, mos emas, taqiqlangan yoki ma’muriy hududlarni kesib o‘tadigan bo‘lishi mumkin. Biznes ma’lumotlari ham noaniq yoki chala bo‘lishi mumkin. Ma’lumotlar real vaqt rejimida bo‘lmasligi hamda joylashuv ma’lumotining aniqligi kafolatlanmaydi. Avtomobilni haydash mobaynida Android Auto xizmati bilan bog‘liq bo‘lmagan hollarda mobil qurilma yoki ilovalardan foydalanmang."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 8108810..a95e312 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Chỉ\nưu tiên"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Chỉ\nbáo thức"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Tất cả"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Tất cả\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Đang sạc (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho đến khi đầy)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Sạc nhanh (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho tới khi đầy)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sạc chậm (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho tới khi đầy)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Màn hình chính"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Gần đây"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Quay lại"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Hiển thị không làm phiền theo âm lượng"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Cho phép kiểm soát toàn bộ tính năng không làm phiền trong hộp thoại âm lượng."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Âm lượng và Không làm phiền"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Truy cập không làm phiền khi giảm âm lượng"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Thoát không làm phiền khi tăng âm lượng"</string>
+    <string name="battery" msgid="7498329822413202973">"Pin"</string>
+    <string name="clock" msgid="7416090374234785905">"Đồng hồ"</string>
+    <string name="headset" msgid="4534219457597457353">"Tai nghe"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Đã kết nối tai nghe"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Đã kết nối tai nghe"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Bật hoặc tắt biểu tượng hiển thị trong thanh trạng thái."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings_car.xml b/packages/SystemUI/res/values-vi/strings_car.xml
new file mode 100644
index 0000000..2aee7d5
--- /dev/null
+++ b/packages/SystemUI/res/values-vi/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Lái xe an toàn"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Luôn biết rõ điều kiện lái xe và luôn tuân thủ luật pháp hiện hành. Chỉ đường có thể không chính xác, không hoàn chỉnh, nguy hiểm, không thích hợp, bị cấm hoặc bao gồm tuyến đường giao các khu vực hành chính. Thông tin doanh nghiệp cũng có thể không chính xác hoặc không hoàn chỉnh. Dữ liệu không ở thời gian thực và không thể đảm bảo độ chính xác của vị trí. Không sử dụng thiết bị di động của bạn hoặc sử dụng ứng dụng không dành cho Android Auto trong khi lái xe."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 1829519..e276fb5 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"仅限\n优先打扰"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"仅限\n闹钟"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"全部"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"全部\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"正在充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"正在快速充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"正在慢速充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主屏幕"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"在音量对话框中显示“请勿打扰”模式"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"允许在音量对话框中完全控制“请勿打扰”模式。"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"音量和“请勿打扰”设置"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"按音量调低键时进入“请勿打扰”模式"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"按音量调高键时退出“请勿打扰”模式"</string>
+    <string name="battery" msgid="7498329822413202973">"电池"</string>
+    <string name="clock" msgid="7416090374234785905">"时钟"</string>
+    <string name="headset" msgid="4534219457597457353">"耳机"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"已连接到耳机"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"已连接到耳机"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"指定在状态栏中显示或隐藏图标。"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_car.xml b/packages/SystemUI/res/values-zh-rCN/strings_car.xml
new file mode 100644
index 0000000..6a5a4e8
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rCN/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"安全驾驶"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"请充分了解驾驶条件并务必遵守适用的法律。路线指示可能不准确,不完整,也可能包含危险、不适合通行、禁止通行或跨越行政区域的路段。商家信息也可能不准确或不完整。数据并非实时提供,因此无法保证位置信息的精确度。请勿在驾驶过程中操作您的移动设备或使用不支持 Android Auto 的应用。"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 5d268e8..86f78e4 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅限\n優先"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"僅限\n鬧鐘"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"全部"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"全部\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"充電中 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後完成充電)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"正在快速充電 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後完成充電)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"正在緩慢充電 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後完成充電)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近的活動"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"在音量對話框中顯示「請勿騷擾」設定"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"允許在音量對話框中全面控制「請勿騷擾」功能。"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"音量和「請勿騷擾」設定"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"調低音量時啟用「請勿騷擾」模式"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"調高音量時停用「請勿騷擾」模式"</string>
+    <string name="battery" msgid="7498329822413202973">"電池"</string>
+    <string name="clock" msgid="7416090374234785905">"時鐘"</string>
+    <string name="headset" msgid="4534219457597457353">"耳機"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"已連接至耳機"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"已連接至耳機"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"顯示或隱藏狀態列上的圖示。"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings_car.xml b/packages/SystemUI/res/values-zh-rHK/strings_car.xml
new file mode 100644
index 0000000..18f9e50
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rHK/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"請安全駕駛"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"請隨時留意路面情況,並遵守適用的交通規則。系統提供的路線可能不準確、不完整、存在危險、不適合、禁止通行,或涉及跨越行政區域的路段。此外,商家資訊也可能不準確或不完整。路況資料並非即時更新,也無法保證定位資訊的準確性。駕駛時請勿操作流動裝置,或使用不適用於 Android Auto 的應用程式。"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 676e003..00eb788 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅允許\n優先通知"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"僅允許\n鬧鐘"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"全部"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"全部\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"充電中 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後充飽)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"快速充電中 (充飽需要 <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"慢速充電中 (充飽需要 <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"近期活動"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"在音量對話方塊中顯示「零打擾」設定"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"在音量對話方塊中顯示完整的「零打擾」設定。"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"音量和「零打擾」設定"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"按下調低音量鍵時啟用「零打擾」模式"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"按下調高音量鍵時停用「零打擾」模式"</string>
+    <string name="battery" msgid="7498329822413202973">"電池"</string>
+    <string name="clock" msgid="7416090374234785905">"時鐘"</string>
+    <string name="headset" msgid="4534219457597457353">"耳機"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"已與耳機連線"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"已與耳機連線"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"指定在狀態列中顯示或隱藏圖示。"</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_car.xml b/packages/SystemUI/res/values-zh-rTW/strings_car.xml
new file mode 100644
index 0000000..5e18309
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rTW/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"安全駕駛"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"請隨時注意周遭路況並遵守交通規則。系統所提供的路線可能有誤、不完整,或包含危險、不合適、禁止通行或管制區域的路段;此外,商家資訊也可能有誤或不完整。路況資料並非即時更新,也無法保證定位資訊必然準確無誤。駕駛時請勿操作您的行動裝置,或使用不適用於 Android Auto 的應用程式。"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 94b9081..08dc7cc 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -332,8 +332,7 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Okubalulekile\nkuphela"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ama-alamu\nkuphela"</string>
     <string name="interruption_level_all" msgid="1330581184930945764">"Konke"</string>
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Konke\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Iyashaja (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Iyashaja ngokushesha (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Iyashaja kancane (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
@@ -483,14 +482,21 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekhaya"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Okwakamuva"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Emuva"</string>
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Bonisa ukungaphazamisi kuvolumu"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Vumela ulawulo olugcwele lokungaphazamisi kungxoxo yevolumu."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Ivolumu nokungaphazamisi"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Faka ukungaphazamisi ekwehliseni ivolumu"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Phuma kokuthi ungaphazamisi ekukhuphuleni ivolumu"</string>
+    <string name="battery" msgid="7498329822413202973">"Ibhethri"</string>
+    <string name="clock" msgid="7416090374234785905">"Iwashi"</string>
+    <string name="headset" msgid="4534219457597457353">"Ama-earphone"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Amahedfoni axhunyiwe"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Ama-earphone axhunyiwe"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Nika amandla noma khubaza izithonjana kusukela ekubonisweni kubha yesimo."</string>
+    <!-- no translation found for data_saver (5037565123367048522) -->
     <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
     <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) -->
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings_car.xml b/packages/SystemUI/res/values-zu/strings_car.xml
new file mode 100644
index 0000000..83301ac
--- /dev/null
+++ b/packages/SystemUI/res/values-zu/strings_car.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Shayela ngokuqophelela"</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Hlala wazi ngokugcwele izimo zokushayela uphinde uthobele yonke imithetho esebenzayo. Izikhombisi-ndlela kungenzeka azilungile, aziphelele, ziyingozi, azifanelekile, zivinjiwe, noma zifaka ukweqa izindawo zokulawula. Ulwazi lwebhizinisi kungenzeka lungalungi noma lungapheleli. Idatha akuyona isikhathi sangempela, futhi ukunemba kwendawo akukwazi ukuqinisekiswa. Ungaphathi idivayisi yakho yeselula noma usebenzise izinhlelo zokusebenza ezihloselwe i-Android Auto ngenkathi ushayela."</string>
+</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index b2190ec..5e25d2c 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -78,14 +78,13 @@
     <color name="notification_material_background_color">#ffffffff</color>
 
     <!-- The color of the material notification background when dimmed -->
-    <color name="notification_material_background_dimmed_color">#f2ffffff</color>
+    <color name="notification_material_background_dimmed_color">#ccffffff</color>
 
     <!-- The color of the material notification background when low priority -->
     <color name="notification_material_background_low_priority_color">#fff5f5f5</color>
 
-    <!-- The color of the material notification background for media notifications when no custom
-         color is specified -->
-    <color name="notification_material_background_media_default_color">#ff424242</color>
+    <!-- The background color of the notification shade -->
+    <color name="notification_shade_background_color">#ffeeeeee</color>
 
     <!-- The color of the ripples on the untinted notifications -->
     <color name="notification_ripple_untinted_color">#28000000</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index aedc2c5..6df31ff 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -181,7 +181,10 @@
     <integer name="recents_animate_task_stack_scroll_duration">200</integer>
 
     <!-- The animation duration for scrolling the stack to a particular item. -->
-    <integer name="recents_auto_advance_duration">2000</integer>
+    <integer name="recents_auto_advance_duration">750</integer>
+
+    <!-- The animation duration for subsequent scrolling the stack to a particular item. -->
+    <integer name="recents_subsequent_auto_advance_duration">1000</integer>
 
     <!-- The animation duration for entering and exiting the history. -->
     <integer name="recents_history_transition_duration">250</integer>
@@ -195,6 +198,10 @@
     <!-- Svelte specific logic, see RecentsConfiguration.SVELTE_* constants. -->
     <integer name="recents_svelte_level">0</integer>
 
+    <!-- In multi-window, determines whether the stack where recents lives should grow from
+         the smallest position when being launched. -->
+    <bool name="recents_grow_in_multiwindow">true</bool>
+
     <!-- Recents: The relative range of visible tasks from the current scroll position
          while the stack is focused. -->
     <item name="recents_layout_focused_range_min" format="float" type="integer">-3</item>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 46a0f2a..8b0350a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -87,9 +87,6 @@
     <!-- gap on either side of status bar notification icons -->
     <dimen name="status_bar_icon_padding">0dp</dimen>
 
-    <!-- half the distance between notifications in the panel -->
-    <dimen name="notification_divider_height">2dp</dimen>
-
     <!-- The padding on the global screenshot background image -->
     <dimen name="global_screenshot_bg_padding">20dp</dimen>
 
@@ -137,9 +134,11 @@
 
     <!-- Width for the notification panel and related windows -->
     <dimen name="match_parent">-1px</dimen>
-    <dimen name="standard_notification_panel_width">416dp</dimen><!-- includes notification_side_padding on each side -->
+    <dimen name="standard_notification_panel_width">416dp</dimen>
     <dimen name="notification_panel_width">@dimen/match_parent</dimen>
 
+    <dimen name="volume_dialog_panel_width">@dimen/standard_notification_panel_width</dimen>
+
     <!-- Gravity for the notification panel -->
     <integer name="standard_notification_panel_layout_gravity">0x31</integer><!-- top|center_horizontal -->
     <integer name="notification_panel_layout_gravity">0x37</integer><!-- fill_horizontal|top -->
@@ -298,17 +297,14 @@
     <!-- The height of the area before the top stack in which the notifications slow down -->
     <dimen name="top_stack_slow_down_length">12dp</dimen>
 
-    <!-- The side padding of the notifications-->
-    <dimen name="notification_side_padding">8dp</dimen>
-
     <!-- Z distance between notifications if they are in the stack -->
-    <dimen name="z_distance_between_notifications">1dp</dimen>
+    <dimen name="z_distance_between_notifications">0.5dp</dimen>
 
-    <!-- The padding between the individual notification cards when dimmed. -->
-    <dimen name="notification_padding_dimmed">0dp</dimen>
+    <!-- The height of the divider between the individual notifications. -->
+    <dimen name="notification_divider_height">0.5dp</dimen>
 
-    <!-- The padding between the individual notification cards. -->
-    <dimen name="notification_padding">2dp</dimen>
+    <!-- The height of the divider between the individual notifications when the notification wants it to be increased. This is currently the case for notification groups -->
+    <dimen name="notification_divider_height_increased">6dp</dimen>
 
     <!-- The minimum amount of top overscroll to go to the quick settings. -->
     <dimen name="min_top_overscroll_to_qs">36dp</dimen>
@@ -328,8 +324,6 @@
     <!-- Falsing threshold used when dismissing notifications from the lockscreen. -->
     <dimen name="swipe_helper_falsing_threshold">70dp</dimen>
 
-    <dimen name="notifications_top_padding">4dp</dimen>
-
     <!-- Minimum distance the user has to drag down to go to the full shade. -->
     <dimen name="keyguard_drag_down_min_distance">100dp</dimen>
 
@@ -374,21 +368,12 @@
          phone hints. -->
     <dimen name="edge_tap_area_width">48dp</dimen>
 
-    <!-- radius of the corners of the material rounded rect background -->
-    <dimen name="notification_material_rounded_rect_radius">2dp</dimen>
-
-    <!-- radius of the corners of the material rounded rect background but negative-->
-    <dimen name="notification_material_rounded_rect_radius_negative">-2dp</dimen>
-
     <!-- The padding between notification children when collapsed -->
     <dimen name="notification_children_padding">4dp</dimen>
 
     <!-- The padding on top of the first notification to the children container -->
     <dimen name="notification_children_container_top_padding">8dp</dimen>
 
-    <!-- The height of the divider between the notfication children -->
-    <dimen name="notification_children_divider_height">1dp</dimen>
-
     <!-- The vertical distance from which the notification appear when children are expanded -->
     <dimen name="notification_appear_distance">140dp</dimen>
 
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
index ecdccee..04402b7 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -18,15 +18,15 @@
 <resources>
     <dimen name="car_lockscreen_disclaimer_title_size">48sp</dimen>
     <dimen name="car_lockscreen_disclaimer_title_padding_start">96dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_title_padding_top">96dp</dimen>
+    <dimen name="car_lockscreen_disclaimer_title_padding_top">82dp</dimen>
     <dimen name="car_lockscreen_disclaimer_text_size">28sp</dimen>
     <dimen name="car_lockscreen_disclaimer_text_padding_start">96dp</dimen>
     <dimen name="car_lockscreen_disclaimer_text_padding_end">96dp</dimen>
-    <dimen name="car_lockscreen_disclaimer_text_padding_top">32dp</dimen>
+    <dimen name="car_lockscreen_disclaimer_text_padding_top">8dp</dimen>
     <dimen name="car_lockscreen_user_grid_view_padding_start">10dp</dimen>
     <dimen name="car_lockscreen_user_grid_view_padding_end">10dp</dimen>
-    <dimen name="car_lockscreen_user_grid_view_padding_top">128dp</dimen>
     <dimen name="car_fullscreen_user_pod_image_avatar_width">128dp</dimen>
     <dimen name="car_fullscreen_user_pod_image_avatar_height">128dp</dimen>
     <dimen name="car_fullscreen_user_pod_text_size">24sp</dimen>
+    <dimen name="car_navigation_button_width">64dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 0bd350b..87aedab 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -18,22 +18,22 @@
 <resources>
     <item type="id" name="translation_y_animator_tag"/>
     <item type="id" name="translation_z_animator_tag"/>
-    <item type="id" name="scale_animator_tag"/>
     <item type="id" name="alpha_animator_tag"/>
     <item type="id" name="top_inset_animator_tag"/>
     <item type="id" name="height_animator_tag"/>
+    <item type="id" name="shadow_alpha_animator_tag"/>
     <item type="id" name="translation_y_animator_end_value_tag"/>
     <item type="id" name="translation_z_animator_end_value_tag"/>
-    <item type="id" name="scale_animator_end_value_tag"/>
     <item type="id" name="alpha_animator_end_value_tag"/>
     <item type="id" name="top_inset_animator_end_value_tag"/>
     <item type="id" name="height_animator_end_value_tag"/>
+    <item type="id" name="shadow_alpha_animator_end_value_tag"/>
     <item type="id" name="translation_y_animator_start_value_tag"/>
     <item type="id" name="translation_z_animator_start_value_tag"/>
-    <item type="id" name="scale_animator_start_value_tag"/>
     <item type="id" name="alpha_animator_start_value_tag"/>
     <item type="id" name="top_inset_animator_start_value_tag"/>
     <item type="id" name="height_animator_start_value_tag"/>
+    <item type="id" name="shadow_alpha_animator_start_value_tag"/>
     <item type="id" name="doze_saved_filter_tag"/>
     <item type="id" name="qs_icon_tag"/>
     <item type="id" name="scrim"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 814e7ea..a490635 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -359,6 +359,9 @@
     <!-- Content description of the data connection with no SIM for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_no_sim">No SIM.</string>
 
+    <!-- Content description of the cell data being disabled. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_cell_data_off">Cellular Data Off</string>
+
     <!-- Content description of the bluetooth tethering icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_bluetooth_tether">Bluetooth tethering.</string>
 
@@ -1179,11 +1182,6 @@
     <!-- Description for the toggle for fast-toggling recents via the recents button. DO NOT TRANSLATE -->
     <string name="overview_fast_toggle_via_button_desc">Enable launch timeout while paging</string>
 
-    <!-- Toggles the fast-toggling indicator. DO NOT TRANSLATE -->
-    <string name="overview_fast_toggle_indicator">Enable fast toggle indicator</string>
-    <!-- Description for the fast-toggling indicator. DO NOT TRANSLATE -->
-    <string name="overview_fast_toggle_indicator_desc">Show an indicator for the launch timeout</string>
-
     <!-- Toggle to set the initial scroll state to be paging or stack. DO NOT TRANSLATE -->
     <string name="overview_initial_state_paging">Initialize to paging</string>
     <!-- Description for the toggle to set the initial scroll state to be paging or stack. DO NOT TRANSLATE -->
@@ -1333,4 +1331,13 @@
     <!-- Explanation of the status bar section of the tuner [CHAR LIMIT=NONE] -->
     <string name="tuner_status_bar_explanation">Enable or disable icons from being shown in the status bar.</string>
 
+    <!-- Label for quick settings tile for data saver [CHAR LIMIT=30] -->
+    <string name="data_saver">Data Saver</string>
+
+    <!-- Accessibility description for data saver being on [CHAR LIMIT=NONE] -->
+    <string name="accessibility_data_saver_on">Data Saver is on</string>
+
+    <!-- Accessibility description for data saver being off [CHAR LIMIT=NONE] -->
+    <string name="accessibility_data_saver_off">Data Saver is off</string>
+
 </resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 9193754..67a7a23 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -122,12 +122,6 @@
             android:title="@string/overview_fast_toggle_via_button"
             android:summary="@string/overview_fast_toggle_via_button_desc" />
 
-        <com.android.systemui.tuner.TunerSwitch
-            android:key="overview_fast_toggle_indicator"
-            android:title="@string/overview_fast_toggle_indicator"
-            android:summary="@string/overview_fast_toggle_indicator_desc"
-            android:dependency="overview_fast_toggle_via_button" />
-
     </PreferenceScreen>
 
     <SwitchPreference
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
index 99028a6c..001d1f2 100644
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -32,7 +32,7 @@
     /**
      * Docks the top-most task and opens recents.
      */
-    boolean dockTopTask(boolean draggingInRecents, int stackCreateMode, Rect initialBounds);
+    boolean dockTopTask(int dragMode, int stackCreateMode, Rect initialBounds);
 
     /**
      * Called during a drag-from-navbar-in gesture.
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index fd4161f..5b955a4 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -30,11 +30,9 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
 
 import com.android.systemui.classifier.FalsingManager;
+import com.android.systemui.statusbar.Interpolators;
 
 public class SwipeHelper implements Gefingerpoken {
     static final String TAG = "com.android.systemui.SwipeHelper";
@@ -48,9 +46,6 @@
     public static final int X = 0;
     public static final int Y = 1;
 
-    private static LinearInterpolator sLinearInterpolator = new LinearInterpolator();
-    private final Interpolator mFastOutLinearInInterpolator;
-
     private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
     private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
     private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
@@ -97,8 +92,6 @@
         mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
 
         mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press!
-        mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
-                android.R.interpolator.fast_out_linear_in);
         mFalsingThreshold = context.getResources().getDimensionPixelSize(
                 R.dimen.swipe_helper_falsing_threshold);
         mFalsingManager = FalsingManager.getInstance(context);
@@ -357,9 +350,9 @@
         }
         ObjectAnimator anim = createTranslationAnimation(animView, newPos);
         if (useAccelerateInterpolator) {
-            anim.setInterpolator(mFastOutLinearInInterpolator);
+            anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
         } else {
-            anim.setInterpolator(sLinearInterpolator);
+            anim.setInterpolator(Interpolators.LINEAR);
         }
         anim.setDuration(duration);
         if (delay > 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java b/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
index c9ba885..25f8bb0 100644
--- a/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
@@ -24,8 +24,8 @@
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.view.View;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
+
+import com.android.systemui.statusbar.Interpolators;
 
 import java.util.ArrayList;
 
@@ -35,7 +35,6 @@
 public class ViewInvertHelper {
 
     private final Paint mDarkPaint = new Paint();
-    private final Interpolator mLinearOutSlowInInterpolator;
     private final ColorMatrix mMatrix = new ColorMatrix();
     private final ColorMatrix mGrayscaleMatrix = new ColorMatrix();
     private final long mFadeDuration;
@@ -46,8 +45,6 @@
         addTarget(v);
     }
     public ViewInvertHelper(Context context, long fadeDuration) {
-        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
-                android.R.interpolator.linear_out_slow_in);
         mFadeDuration = fadeDuration;
     }
 
@@ -89,7 +86,7 @@
             }
         });
         animator.setDuration(mFadeDuration);
-        animator.setInterpolator(mLinearOutSlowInInterpolator);
+        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
         animator.setStartDelay(delay);
         animator.start();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
index c3a8f2e..92cd027 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.assist;
 
-import com.android.systemui.R;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
@@ -35,6 +33,9 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
 
+import com.android.systemui.R;
+import com.android.systemui.statusbar.Interpolators;
+
 /**
  * Visually discloses that contextual data was provided to an assistant.
  */
@@ -120,13 +121,11 @@
                     R.interpolator.assist_disclosure_trace));
             mAlphaInAnimator = ValueAnimator.ofInt(0, 255).setDuration(ALPHA_IN_ANIMATION_DURATION);
             mAlphaInAnimator.addUpdateListener(this);
-            mAlphaInAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
-                    android.R.interpolator.fast_out_slow_in));
+            mAlphaInAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
             mAlphaOutAnimator = ValueAnimator.ofInt(255, 0).setDuration(
                     ALPHA_OUT_ANIMATION_DURATION);
             mAlphaOutAnimator.addUpdateListener(this);
-            mAlphaOutAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
-                    android.R.interpolator.fast_out_linear_in));
+            mAlphaOutAnimator.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
             mAnimator = new AnimatorSet();
             mAnimator.play(mAlphaInAnimator).with(mTracingAnimator);
             mAnimator.play(mAlphaInAnimator).before(mAlphaOutAnimator);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java
index 67017db..34770c4 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbContainer.java
@@ -20,19 +20,15 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.Interpolators;
 
 public class AssistOrbContainer extends FrameLayout {
 
     private static final long EXIT_START_DELAY = 150;
 
-    private final Interpolator mLinearOutSlowInInterpolator;
-    private final Interpolator mFastOutLinearInInterpolator;
-
     private View mScrim;
     private View mNavbarScrim;
     private AssistOrbView mOrb;
@@ -49,10 +45,6 @@
 
     public AssistOrbContainer(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
-                android.R.interpolator.linear_out_slow_in);
-        mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
-                android.R.interpolator.fast_out_slow_in);
     }
 
     @Override
@@ -109,12 +101,12 @@
                         .alpha(1f)
                         .setDuration(300)
                         .setStartDelay(0)
-                        .setInterpolator(mLinearOutSlowInInterpolator);
+                        .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
                 mNavbarScrim.animate()
                         .alpha(1f)
                         .setDuration(300)
                         .setStartDelay(0)
-                        .setInterpolator(mLinearOutSlowInInterpolator);
+                        .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
             }
         });
     }
@@ -132,12 +124,12 @@
                 .alpha(0f)
                 .setDuration(250)
                 .setStartDelay(EXIT_START_DELAY)
-                .setInterpolator(mFastOutLinearInInterpolator);
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         mNavbarScrim.animate()
                 .alpha(0f)
                 .setDuration(250)
                 .setStartDelay(EXIT_START_DELAY)
-                .setInterpolator(mFastOutLinearInInterpolator)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 .withEndAction(endRunnable);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java
index a3372a8..2d933f6 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java
@@ -27,13 +27,13 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewOutlineProvider;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.OvershootInterpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.Interpolators;
 
 public class AssistOrbView extends FrameLayout {
 
@@ -43,8 +43,6 @@
     private final Paint mBackgroundPaint = new Paint();
     private final Rect mCircleRect = new Rect();
     private final Rect mStaticRect = new Rect();
-    private final Interpolator mAppearInterpolator;
-    private final Interpolator mDisappearInterpolator;
     private final Interpolator mOvershootInterpolator = new OvershootInterpolator();
 
     private boolean mClipToOutline;
@@ -117,10 +115,6 @@
                 R.dimen.assist_orb_travel_distance);
         mMaxElevation = context.getResources().getDimensionPixelSize(
                 R.dimen.assist_orb_elevation);
-        mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.linear_out_slow_in);
-        mDisappearInterpolator = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.fast_out_linear_in);
         mBackgroundPaint.setAntiAlias(true);
         mBackgroundPaint.setColor(getResources().getColor(R.color.assist_orb_color));
     }
@@ -256,8 +250,8 @@
     }
 
     public void startExitAnimation(long delay) {
-        animateCircleSize(0, 200, delay, mDisappearInterpolator);
-        animateOffset(0, 200, delay, mDisappearInterpolator);
+        animateCircleSize(0, 200, delay, Interpolators.FAST_OUT_LINEAR_IN);
+        animateOffset(0, 200, delay, Interpolators.FAST_OUT_LINEAR_IN);
     }
 
     public void startEnterAnimation() {
@@ -266,7 +260,7 @@
             @Override
             public void run() {
                 animateCircleSize(mCircleMinSize, 300, 0 /* delay */, mOvershootInterpolator);
-                animateOffset(mStaticOffset, 400, 0 /* delay */, mAppearInterpolator);
+                animateOffset(mStaticOffset, 400, 0 /* delay */, Interpolators.LINEAR_OUT_SLOW_IN);
             }
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 704de97..0475c72 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -84,6 +84,10 @@
 import java.util.List;
 
 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
 
 /**
  * Mediates requests related to the keyguard.  This includes queries about the
@@ -550,14 +554,28 @@
         @Override
         public int getBouncerPromptReason() {
             int currentUser = ActivityManager.getCurrentUser();
-            if ((mUpdateMonitor.getUserTrustIsManaged(currentUser)
-                    || mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser))
-                    && !mUpdateMonitor.getStrongAuthTracker().hasUserAuthenticatedSinceBoot()) {
+            boolean trust = mTrustManager.isTrustUsuallyManaged(currentUser);
+            boolean fingerprint = mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser);
+            boolean any = trust || fingerprint;
+            KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
+                    mUpdateMonitor.getStrongAuthTracker();
+            int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);
+
+            if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
                 return KeyguardSecurityView.PROMPT_REASON_RESTART;
-            } else if (mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser)
-                    && mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) {
+            } else if (fingerprint && mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) {
                 return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
+            } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
+                return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
+            } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
+                return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
+            } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
+                return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
+            } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL) != 0) {
+                return KeyguardSecurityView.PROMPT_REASON_WRONG_CREDENTIAL;
             }
+
+
             return KeyguardSecurityView.PROMPT_REASON_NONE;
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index b5f146b..8979023 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -34,7 +34,9 @@
 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;
@@ -245,7 +247,7 @@
     public void setExpanded(boolean expanded) {
         if (mExpanded == expanded) return;
         mExpanded = expanded;
-        MetricsLogger.visibility(mContext, MetricsLogger.QS_PANEL, mExpanded);
+        MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, mExpanded);
         if (!mExpanded) {
             closeDetail();
         } else {
@@ -498,7 +500,7 @@
         int newVis = visible ? VISIBLE : INVISIBLE;
         mQsContainer.setVisibility(newVis);
         if (mGridContentVisible != visible) {
-            MetricsLogger.visibility(mContext, MetricsLogger.QS_PANEL, newVis);
+            MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, newVis);
         }
         mGridContentVisible = visible;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 72629a3..20e2fa4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -82,9 +82,8 @@
     /**
      * Declare the category of this tile.
      *
-     * Categories are defined in {@link com.android.internal.logging.MetricsLogger}
-     * or if there is no relevant existing category you may define one in
-     * {@link com.android.systemui.qs.QSTile}.
+     * Categories are defined in {@link com.android.internal.logging.MetricsProto.MetricsEvent}
+     * by editing frameworks/base/proto/src/metrics_constants.proto.
      */
     abstract public int getMetricsCategory();
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java
index ac4f05f..36bed0d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java
@@ -20,7 +20,9 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.graphics.drawable.Drawable;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 
@@ -84,6 +86,6 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_INTENT;
+        return MetricsEvent.QS_INTENT;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 6e22dde..8ae2d7b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -73,7 +73,7 @@
             mCurrentTiles = tileSpecs;
             final TileGroup group = new TileGroup("com.android.settings", mContext);
             String possible = mContext.getString(R.string.quick_settings_tiles_default)
-                    + ",user,hotspot,inversion";
+                    + ",hotspot,inversion,saver";
             String[] possibleTiles = possible.split(",");
             for (int i = 0; i < possibleTiles.length; i++) {
                 final String spec = possibleTiles[i];
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index d398b64..886531a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -31,7 +31,9 @@
 import android.view.IWindowManager;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.phone.QSTileHost;
@@ -197,7 +199,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_CUSTOM;
+        return MetricsEvent.QS_CUSTOM;
     }
 
     public void startUnlockAndRun() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index c696f88..d78d6ff 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -24,6 +24,7 @@
 import android.provider.Settings.Global;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.GlobalSetting;
 import com.android.systemui.qs.QSTile;
@@ -85,7 +86,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_AIRPLANEMODE;
+        return MetricsEvent.QS_AIRPLANEMODE;
     }
 
     @Override
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 60238fc3..fd8857d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -25,7 +25,7 @@
 import android.widget.Checkable;
 import android.widget.ImageView;
 import android.widget.TextView;
-import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settingslib.BatteryInfo;
 import com.android.systemui.BatteryMeterDrawable;
 import com.android.systemui.R;
@@ -64,7 +64,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_BATTERY_TILE;
+        return MetricsEvent.QS_BATTERY_TILE;
     }
 
     @Override
@@ -199,7 +199,7 @@
 
         @Override
         public int getMetricsCategory() {
-            return MetricsLogger.QS_BATTERY_DETAIL;
+            return MetricsEvent.QS_BATTERY_DETAIL;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 3750290..6a07a07 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -24,7 +24,9 @@
 import android.text.TextUtils;
 import android.view.View;
 import android.view.ViewGroup;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSDetailItems;
@@ -127,7 +129,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_BLUETOOTH;
+        return MetricsEvent.QS_BLUETOOTH;
     }
 
     @Override
@@ -181,14 +183,14 @@
 
         @Override
         public void setToggleState(boolean state) {
-            MetricsLogger.action(mContext, MetricsLogger.QS_BLUETOOTH_TOGGLE, state);
+            MetricsLogger.action(mContext, MetricsEvent.QS_BLUETOOTH_TOGGLE, state);
             mController.setBluetoothEnabled(state);
             showDetail(false);
         }
 
         @Override
         public int getMetricsCategory() {
-            return MetricsLogger.QS_BLUETOOTH_DETAILS;
+            return MetricsEvent.QS_BLUETOOTH_DETAILS;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index de4c21c..18eb7a1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -23,7 +23,9 @@
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewGroup;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSDetailItems;
 import com.android.systemui.qs.QSDetailItems.Item;
@@ -125,7 +127,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_CAST;
+        return MetricsEvent.QS_CAST;
     }
 
     @Override
@@ -181,7 +183,7 @@
 
         @Override
         public int getMetricsCategory() {
-            return MetricsLogger.QS_CAST_DETAILS;
+            return MetricsEvent.QS_CAST_DETAILS;
         }
 
         @Override
@@ -255,7 +257,7 @@
         @Override
         public void onDetailItemClick(Item item) {
             if (item == null || item.tag == null) return;
-            MetricsLogger.action(mContext, MetricsLogger.QS_CAST_SELECT);
+            MetricsLogger.action(mContext, MetricsEvent.QS_CAST_SELECT);
             final CastDevice device = (CastDevice) item.tag;
             mController.startCasting(device);
         }
@@ -263,7 +265,7 @@
         @Override
         public void onDetailItemDisconnect(Item item) {
             if (item == null || item.tag == null) return;
-            MetricsLogger.action(mContext, MetricsLogger.QS_CAST_DISCONNECT);
+            MetricsLogger.action(mContext, MetricsEvent.QS_CAST_DISCONNECT);
             final CastDevice device = (CastDevice) item.tag;
             mController.stopCasting(device);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 1f8fae0..aacdbc9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -23,7 +23,9 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSIconView;
@@ -89,7 +91,7 @@
     protected void handleSecondaryClick() {
         boolean dataEnabled = mDataController.isMobileDataSupported()
                 && mDataController.isMobileDataEnabled();
-        MetricsLogger.action(mContext, MetricsLogger.QS_CELLULAR_TOGGLE, !dataEnabled);
+        MetricsLogger.action(mContext, MetricsEvent.QS_CELLULAR_TOGGLE, !dataEnabled);
         mDataController.setMobileDataEnabled(!dataEnabled);
     }
 
@@ -131,7 +133,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_CELLULAR;
+        return MetricsEvent.QS_CELLULAR;
     }
 
     // Remove the period from the network name
@@ -241,13 +243,13 @@
 
         @Override
         public void setToggleState(boolean state) {
-            MetricsLogger.action(mContext, MetricsLogger.QS_CELLULAR_TOGGLE, state);
+            MetricsLogger.action(mContext, MetricsEvent.QS_CELLULAR_TOGGLE, state);
             mDataController.setMobileDataEnabled(state);
         }
 
         @Override
         public int getMetricsCategory() {
-            return MetricsLogger.QS_DATAUSAGEDETAIL;
+            return MetricsEvent.QS_DATAUSAGEDETAIL;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 23a15b9..6e843e9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -17,7 +17,9 @@
 package com.android.systemui.qs.tiles;
 
 import android.provider.Settings.Secure;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.SecureSetting;
@@ -84,7 +86,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_COLORINVERSION;
+        return MetricsEvent.QS_COLORINVERSION;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
new file mode 100644
index 0000000..1aeb0fe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles;
+
+import com.android.internal.logging.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.policy.DataSaverController;
+
+public class DataSaverTile extends QSTile<QSTile.BooleanState> implements
+        DataSaverController.Listener{
+
+    private final DataSaverController mDataSaverController;
+
+    public DataSaverTile(Host host) {
+        super(host);
+        mDataSaverController = host.getNetworkController().getDataSaverController();
+    }
+
+    @Override
+    protected BooleanState newTileState() {
+        return new BooleanState();
+    }
+
+    @Override
+    public void setListening(boolean listening) {
+        if (listening) {
+            mDataSaverController.addListener(this);
+        } else {
+            mDataSaverController.remListener(this);
+        }
+    }
+
+    @Override
+    protected void handleClick() {
+        mState.value = !mDataSaverController.isDataSaverEnabled();
+        mDataSaverController.setDataSaverEnabled(mState.value);
+        refreshState(mState.value);
+    }
+
+    @Override
+    protected void handleUpdateState(BooleanState state, Object arg) {
+        state.value = arg instanceof Boolean ? (Boolean) arg
+                : mDataSaverController.isDataSaverEnabled();
+        state.label = mContext.getString(R.string.data_saver);
+        state.contentDescription = mContext.getString(state.value ?
+                R.string.accessibility_data_saver_on : R.string.accessibility_data_saver_off);
+        state.icon = ResourceIcon.get(state.value ? R.drawable.ic_data_saver
+                : R.drawable.ic_data_saver_off);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsEvent.QS_DATA_SAVER;
+    }
+
+    @Override
+    public void onDataSaverChanged(boolean isDataSaving) {
+        refreshState(isDataSaving);
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 39eda6b..1f9f1c4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -30,7 +30,9 @@
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewGroup;
 import android.widget.Toast;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.SysUIToast;
@@ -154,7 +156,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_DND;
+        return MetricsEvent.QS_DND;
     }
 
     @Override
@@ -229,7 +231,7 @@
 
         @Override
         public void setToggleState(boolean state) {
-            MetricsLogger.action(mContext, MetricsLogger.QS_DND_TOGGLE, state);
+            MetricsLogger.action(mContext, MetricsEvent.QS_DND_TOGGLE, state);
             if (!state) {
                 mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
                 showDetail(false);
@@ -238,7 +240,7 @@
 
         @Override
         public int getMetricsCategory() {
-            return MetricsLogger.QS_DND_DETAILS;
+            return MetricsEvent.QS_DND_DETAILS;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 39d9da1..1d9f15b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -17,7 +17,9 @@
 package com.android.systemui.qs.tiles;
 
 import android.app.ActivityManager;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.FlashlightController;
@@ -92,7 +94,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_FLASHLIGHT;
+        return MetricsEvent.QS_FLASHLIGHT;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 55aa32b..db86047 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -17,6 +17,7 @@
 package com.android.systemui.qs.tiles;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.HotspotController;
@@ -75,7 +76,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_HOTSPOT;
+        return MetricsEvent.QS_HOTSPOT;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index 0883445..e1dc9f2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -30,6 +30,7 @@
 import android.util.Log;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.qs.QSTile;
 
 import java.util.Arrays;
@@ -155,7 +156,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_INTENT;
+        return MetricsEvent.QS_INTENT;
     }
 
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index e79aabf..724659c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -17,6 +17,7 @@
 package com.android.systemui.qs.tiles;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -99,7 +100,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_LOCATION;
+        return MetricsEvent.QS_LOCATION;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 79155b2..f920d48 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -18,7 +18,9 @@
 
 import android.content.Context;
 import android.content.res.Configuration;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.RotationLockController;
@@ -108,7 +110,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_ROTATIONLOCK;
+        return MetricsEvent.QS_ROTATIONLOCK;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index b44ef0b..2c8a478 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -24,6 +24,7 @@
 import android.view.ViewGroup;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.systemui.R;
 import com.android.systemui.qs.PseudoGridView;
@@ -94,7 +95,7 @@
                         mContext, tag.enforcedAdmin);
                 mController.startActivity(intent);
             } else {
-                MetricsLogger.action(mContext, MetricsLogger.QS_SWITCH_USER);
+                MetricsLogger.action(mContext, MetricsEvent.QS_SWITCH_USER);
                 switchTo(tag);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
index d29cae4..6eb0646 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
@@ -18,7 +18,7 @@
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.util.Pair;
-import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -52,7 +52,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_USER_TILE;
+        return MetricsEvent.QS_USER_TILE;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 95ea3f8..42296f2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -24,7 +24,9 @@
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settingslib.wifi.AccessPoint;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSDetailItems;
@@ -162,7 +164,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_WIFI;
+        return MetricsEvent.QS_WIFI;
     }
 
     @Override
@@ -256,14 +258,14 @@
         @Override
         public void setToggleState(boolean state) {
             if (DEBUG) Log.d(TAG, "setToggleState " + state);
-            MetricsLogger.action(mContext, MetricsLogger.QS_WIFI_TOGGLE, state);
+            MetricsLogger.action(mContext, MetricsEvent.QS_WIFI_TOGGLE, state);
             mController.setWifiEnabled(state);
             showDetail(false);
         }
 
         @Override
         public int getMetricsCategory() {
-            return MetricsLogger.QS_WIFI_DETAILS;
+            return MetricsEvent.QS_WIFI_DETAILS;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 34ed37b..508490f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -24,7 +24,9 @@
 import android.content.pm.UserInfo;
 import android.os.UserHandle;
 import android.os.UserManager;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 
@@ -124,7 +126,7 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_WORKMODE;
+        return MetricsEvent.QS_WORKMODE;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
index b36b95a..37085c7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
+++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl
@@ -16,6 +16,8 @@
 
 package com.android.systemui.recents;
 
+import android.graphics.Rect;
+
 /**
  * Due to the fact that RecentsActivity is per-user, we need to establish an
  * interface (this) for the system user to callback to the secondary users in
@@ -29,6 +31,8 @@
     void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
     void toggleRecents();
     void onConfigurationChanged();
+    void dockTopTask(int topTaskId, int dragMode, int stackCreateMode,
+            in Rect initialBounds);
     void onDraggingInRecents(float distanceFromTop);
     void onDraggingInRecentsEnded(float velocity);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
index 6b49195..cb8f0e7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
+++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl
@@ -26,4 +26,7 @@
 
     void updateRecentsVisibility(boolean visible);
     void startScreenPinning();
+    void sendRecentsDrawnEvent();
+    void sendDockingTopTaskEvent(int dragMode);
+    void sendLaunchRecentsEvent();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 2baefd5..b8310f2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.recents;
 
+import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -36,8 +37,11 @@
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUI;
 import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.DockingTopTaskEvent;
+import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
+import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 
@@ -366,17 +370,38 @@
     }
 
     @Override
-    public boolean dockTopTask(boolean draggingInRecents, int stackCreateMode, Rect initialBounds) {
+    public boolean dockTopTask(int dragMode, int stackCreateMode, Rect initialBounds) {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
         if (!isUserSetup()) {
             return false;
         }
 
-        if (mImpl.dockTopTask(draggingInRecents, stackCreateMode,initialBounds)) {
-            if (draggingInRecents) {
-                mDraggingInRecentsCurrentUser = sSystemServicesProxy.getCurrentUser();
+        int currentUser = sSystemServicesProxy.getCurrentUser();
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask();
+        boolean screenPinningActive = ssp.isScreenPinningActive();
+        boolean isTopTaskHome = topTask != null && SystemServicesProxy.isHomeStack(topTask.stackId);
+        if (topTask != null && !isTopTaskHome && !screenPinningActive) {
+            if (sSystemServicesProxy.isSystemUser(currentUser)) {
+                mImpl.dockTopTask(topTask.id, dragMode, stackCreateMode, initialBounds);
+            } else {
+                if (mSystemUserCallbacks != null) {
+                    IRecentsNonSystemUserCallbacks callbacks =
+                            mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
+                    if (callbacks != null) {
+                        try {
+                            callbacks.dockTopTask(topTask.id, dragMode, stackCreateMode,
+                                    initialBounds);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Callback failed", e);
+                        }
+                    } else {
+                        Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
+                    }
+                }
             }
+            mDraggingInRecentsCurrentUser = currentUser;
             return true;
         }
         return false;
@@ -516,6 +541,54 @@
         }
     }
 
+    public final void onBusEvent(final RecentsDrawnEvent event) {
+        int processUser = sSystemServicesProxy.getProcessUser();
+        if (!sSystemServicesProxy.isSystemUser(processUser)) {
+            postToSystemUser(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        mCallbacksToSystemUser.sendRecentsDrawnEvent();
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Callback failed", e);
+                    }
+                }
+            });
+        }
+    }
+
+    public final void onBusEvent(final DockingTopTaskEvent event) {
+        int processUser = sSystemServicesProxy.getProcessUser();
+        if (!sSystemServicesProxy.isSystemUser(processUser)) {
+            postToSystemUser(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        mCallbacksToSystemUser.sendDockingTopTaskEvent(event.dragMode);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Callback failed", e);
+                    }
+                }
+            });
+        }
+    }
+
+    public final void onBusEvent(final RecentsActivityStartingEvent event) {
+        int processUser = sSystemServicesProxy.getProcessUser();
+        if (!sSystemServicesProxy.isSystemUser(processUser)) {
+            postToSystemUser(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        mCallbacksToSystemUser.sendLaunchRecentsEvent();
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Callback failed", e);
+                    }
+                }
+            });
+        }
+    }
+
     /**
      * Attempts to register with the system user.
      */
@@ -525,7 +598,8 @@
             @Override
             public void run() {
                 try {
-                    mCallbacksToSystemUser.registerNonSystemUserCallbacks(mImpl, processUser);
+                    mCallbacksToSystemUser.registerNonSystemUserCallbacks(
+                            new RecentsImplProxy(mImpl), processUser);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Failed to register", e);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 3a3b19d..fa30eed 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -37,13 +37,16 @@
 import android.view.ViewStub;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.AppWidgetProviderChangedEvent;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.DebugFlagsChangedEvent;
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
+import com.android.systemui.recents.events.activity.EnterRecentsTaskStackAnimationCompletedEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
@@ -59,6 +62,7 @@
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
 import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
 import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
+import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
 import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
 import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
 import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
@@ -115,6 +119,7 @@
     // The trigger to automatically launch the current task
     private int mFocusTimerDuration;
     private DozeTrigger mIterateTrigger;
+    private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
 
     /**
      * A common Runnable to finish Recents by launching Home with an animation depending on the
@@ -399,7 +404,18 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, ssp, true));
 
-        MetricsLogger.visible(this, MetricsLogger.OVERVIEW_ACTIVITY);
+        MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY);
+
+        mRecentsView.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+
+            @Override
+            public boolean onPreDraw() {
+                mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
+                EventBus.getDefault().post(new RecentsDrawnEvent());
+                return true;
+            }
+        });
     }
 
     @Override
@@ -446,7 +462,7 @@
         launchState.launchedHasConfigurationChanged = false;
         launchState.launchedViaDragGesture = false;
 
-        MetricsLogger.hidden(this, MetricsLogger.OVERVIEW_ACTIVITY);
+        MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
     }
 
     @Override
@@ -537,7 +553,7 @@
                         EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
                     } else {
                         EventBus.getDefault().send(
-                                new FocusNextTaskViewEvent(false /* showTimerIndicator */));
+                                new FocusNextTaskViewEvent(0 /* timerIndicatorDuration */));
                     }
                     mLastTabKeyEventTime = SystemClock.elapsedRealtime();
 
@@ -550,7 +566,7 @@
             }
             case KeyEvent.KEYCODE_DPAD_UP: {
                 EventBus.getDefault().send(
-                        new FocusNextTaskViewEvent(false /* showTimerIndicator */));
+                        new FocusNextTaskViewEvent(0 /* timerIndicatorDuration */));
                 return true;
             }
             case KeyEvent.KEYCODE_DPAD_DOWN: {
@@ -576,10 +592,7 @@
 
     @Override
     public void onUserInteraction() {
-        // TODO: Prevent creating so many events here
-        final RecentsDebugFlags debugFlags = Recents.getDebugFlags();
-        EventBus.getDefault().send(new UserInteractionEvent(debugFlags.isFastToggleRecentsEnabled()
-                && debugFlags.isFastToggleIndicatorEnabled()));
+        EventBus.getDefault().send(mUserInteractionEvent);
     }
 
     @Override
@@ -605,13 +618,13 @@
         if (!dismissHistory()) {
             final RecentsDebugFlags debugFlags = Recents.getDebugFlags();
 
-            // Focus the next task
-            EventBus.getDefault().send(
-                    new FocusNextTaskViewEvent(debugFlags.isFastToggleRecentsEnabled()
-                            && debugFlags.isFastToggleIndicatorEnabled()));
-
             // Start dozing after the recents button is clicked
+            int timerIndicatorDuration = 0;
             if (debugFlags.isFastToggleRecentsEnabled()) {
+                timerIndicatorDuration = getResources().getInteger(
+                        R.integer.recents_subsequent_auto_advance_duration);
+
+                mIterateTrigger.setDozeDuration(timerIndicatorDuration);
                 if (!mIterateTrigger.isDozing()) {
                     mIterateTrigger.startDozing();
                 } else {
@@ -619,7 +632,10 @@
                 }
             }
 
-            MetricsLogger.action(this, MetricsLogger.ACTION_OVERVIEW_PAGE);
+            // Focus the next task
+            EventBus.getDefault().send(new FocusNextTaskViewEvent(timerIndicatorDuration));
+
+            MetricsLogger.action(this, MetricsEvent.ACTION_OVERVIEW_PAGE);
         }
     }
 
@@ -648,6 +664,9 @@
             } else {
                 dismissRecentsToHome(true /* animateTaskViews */);
             }
+
+            // Cancel any pending dozes
+            EventBus.getDefault().send(mUserInteractionEvent);
         } else {
             // Do nothing
         }
@@ -670,6 +689,21 @@
         }
     }
 
+    public final void onBusEvent(EnterRecentsTaskStackAnimationCompletedEvent event) {
+        RecentsDebugFlags debugFlags = Recents.getDebugFlags();
+        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
+        if (!launchState.launchedWithAltTab && debugFlags.isFastToggleRecentsEnabled() &&
+                RecentsDebugFlags.Static.EnableFastToggleTimeoutOnEnter) {
+            mIterateTrigger.setDozeDuration(
+                    getResources().getInteger(R.integer.recents_auto_advance_duration));
+            if (!mIterateTrigger.isDozing()) {
+                mIterateTrigger.startDozing();
+            } else {
+                mIterateTrigger.poke();
+            }
+        }
+    }
+
     public final void onBusEvent(EnterRecentsWindowLastAnimationFrameEvent event) {
         EventBus.getDefault().send(new UpdateFreeformTaskViewVisibilityEvent(true));
         mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
index 4ab0740..0afa1f6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -52,27 +52,12 @@
      * Returns the task to focus given the current launch state.
      */
     public int getInitialFocusTaskIndex(int numTasks) {
-        RecentsDebugFlags flags = Recents.getDebugFlags();
-        if (launchedWithAltTab) {
-            if (launchedFromAppWithThumbnail) {
-                // If alt-tabbing from another app, focus the next task
-                return numTasks - 2;
-            } else {
-                // If alt-tabbing from home, focus the first task
-                return numTasks - 1;
-            }
+        if (launchedFromAppWithThumbnail) {
+            // If coming from another app, focus the next task
+            return numTasks - 2;
         } else {
-            if (launchedFromHome) {
-                return numTasks - 1;
-            } else {
-                if (flags.isFastToggleRecentsEnabled() || !flags.isInitialStatePaging()) {
-                    // If we are not fast-toggling or are starting in the non-focused mode, then
-                    // we should assume the front most task has focus
-                    return numTasks - 1;
-                } else {
-                    return numTasks - 2;
-                }
-            }
+            // If coming from home, focus the first task
+            return numTasks - 1;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
index 881aa6a..49f2ab0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.DebugFlagsChangedEvent;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.tuner.TunerService;
 
 /**
@@ -26,10 +27,6 @@
  */
 public class RecentsDebugFlags implements TunerService.Tunable {
 
-    private static final String KEY_FAST_TOGGLE = "overview_fast_toggle_via_button";
-    private static final String KEY_FAST_TOGGLE_INDICATOR = "overview_fast_toggle_indicator";
-    private static final String KEY_INITIAL_STATE_PAGING = "overview_initial_state_paging";
-
     public static class Static {
         // Enables debug drawing for the transition thumbnail
         public static final boolean EnableTransitionThumbnailDebugMode = false;
@@ -39,20 +36,27 @@
         public static final boolean DisableBackgroundCache = false;
         // Enables the task affiliations
         public static final boolean EnableAffiliatedTaskGroups = true;
-        // Enables the simulated task affiliations
-        public static final boolean EnableSimulatedTaskGroups = false;
-        // Defines the number of mock task affiliations per group
-        public static final int TaskAffiliationsGroupCount = 12;
+        // Overrides the Tuner flags and enables the fast toggle and timeout
+        public static final boolean EnableFastToggleTimeoutOverride = true;
+        // Enables toggling the fast-toggle timeout immediately after entering Recents
+        public static final boolean EnableFastToggleTimeoutOnEnter = true;
+
         // Enables us to create mock recents tasks
-        public static final boolean EnableSystemServicesProxy = false;
+        public static final boolean EnableMockTasks = false;
         // Defines the number of mock recents packages to create
-        public static final int SystemServicesProxyMockPackageCount = 3;
+        public static final int MockTasksPackageCount = 3;
         // Defines the number of mock recents tasks to create
-        public static final int SystemServicesProxyMockTaskCount = 100;
+        public static final int MockTaskCount = 100;
+        // Enables the simulated task affiliations
+        public static final boolean EnableMockTaskGroups = false;
+        // Defines the number of mock task affiliations per group
+        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 boolean mFastToggleRecents;
-    private boolean mFastToggleIndicator;
     private boolean mInitialStatePaging;
 
     /**
@@ -62,28 +66,32 @@
     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_FAST_TOGGLE_INDICATOR,
-                KEY_INITIAL_STATE_PAGING);
+        TunerService.get(context).addTunable(this, KEY_FAST_TOGGLE, KEY_INITIAL_STATE_PAGING);
     }
 
     /**
      * @return whether we are enabling fast toggling.
      */
     public boolean isFastToggleRecentsEnabled() {
+        // These checks EnableFastToggleTimeoutOverride
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        if (ssp.hasFreeformWorkspaceSupport() || ssp.hasDockedTask() ||
+                ssp.isTouchExplorationEnabled()) {
+            return false;
+        }
+        if (Static.EnableFastToggleTimeoutOverride) {
+            return true;
+        }
         return mFastToggleRecents;
     }
 
     /**
-     * @return whether we are enabling the fast toggle indicator.
-     */
-    public boolean isFastToggleIndicatorEnabled() {
-        return mFastToggleRecents && mFastToggleIndicator;
-    }
-
-    /**
      * @return whether the initial stack state is paging.
      */
     public boolean isInitialStatePaging() {
+        if (Static.EnableFastToggleTimeoutOnEnter) {
+            return true;
+        }
         return mInitialStatePaging;
     }
 
@@ -94,10 +102,6 @@
                 mFastToggleRecents = (newValue != null) &&
                         (Integer.parseInt(newValue) != 0);
                 break;
-            case KEY_FAST_TOGGLE_INDICATOR:
-                mFastToggleIndicator = (newValue != null) &&
-                        (Integer.parseInt(newValue) != 0);
-                break;
             case KEY_INITIAL_STATE_PAGING:
                 mInitialStatePaging = (newValue != null) &&
                         (Integer.parseInt(newValue) != 0);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index f8cbf65..b78fd22 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -41,9 +41,11 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
 import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.DockingTopTaskEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.IterateRecentsEvent;
+import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
 import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
 import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
@@ -62,6 +64,7 @@
 import com.android.systemui.recents.views.TaskViewHeader;
 import com.android.systemui.recents.views.TaskViewTransform;
 import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 import java.util.ArrayList;
@@ -72,8 +75,7 @@
  * An implementation of the Recents component for the current user.  For secondary users, this can
  * be called remotely from the system user.
  */
-public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub implements
-        ActivityOptions.OnAnimationFinishedListener {
+public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener {
 
     private final static String TAG = "RecentsImpl";
     // The minimum amount of time between each recents button press that we will handle
@@ -108,6 +110,10 @@
         public void onActivityPinned() {
         }
 
+        @Override
+        public void onPinnedActivityRestartAttempt() {
+        }
+
         /** Preloads the next task */
         public void run() {
             RecentsConfiguration config = Recents.getConfiguration();
@@ -528,18 +534,14 @@
         showRelativeAffiliatedTask(false);
     }
 
-    public boolean dockTopTask(boolean draggingInRecents, int stackCreateMode, Rect initialBounds) {
+    public void dockTopTask(int topTaskId, int dragMode,
+            int stackCreateMode, Rect initialBounds) {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask();
-        boolean screenPinningActive = ssp.isScreenPinningActive();
-        boolean isTopTaskHome = SystemServicesProxy.isHomeStack(topTask.stackId);
-        if (topTask != null && !isTopTaskHome && !screenPinningActive) {
-            ssp.moveTaskToDockedStack(topTask.id, stackCreateMode, initialBounds);
-            showRecents(false /* triggeredFromAltTab */, draggingInRecents, false /* animate */,
-                    true /* reloadTasks*/);
-            return true;
-        }
-        return false;
+        ssp.moveTaskToDockedStack(topTaskId, stackCreateMode, initialBounds);
+        showRecents(false /* triggeredFromAltTab */,
+                dragMode == NavigationBarGestureHelper.DRAG_MODE_RECENTS, false /* animate */,
+                true /* reloadTasks*/);
+        EventBus.getDefault().send(new DockingTopTaskEvent(dragMode));
     }
 
     /**
@@ -914,6 +916,7 @@
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         }
         mCanReuseTaskStackViews = true;
+        EventBus.getDefault().send(new RecentsActivityStartingEvent());
     }
 
     /**** OnAnimationFinishedListener Implementation ****/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
new file mode 100644
index 0000000..86ec98a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.recents;
+
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+
+import com.android.internal.os.SomeArgs;
+
+/**
+ * A proxy class which directs all methods from {@link IRecentsNonSystemUserCallbacks} to
+ * {@link RecentsImpl} and makes sure they are called from the main thread.
+ */
+public class RecentsImplProxy extends IRecentsNonSystemUserCallbacks.Stub {
+
+    private static final int MSG_PRELOAD_RECENTS = 1;
+    private static final int MSG_CANCEL_PRELOADING_RECENTS = 2;
+    private static final int MSG_SHOW_RECENTS = 3;
+    private static final int MSG_HIDE_RECENTS = 4;
+    private static final int MSG_TOGGLE_RECENTS = 5;
+    private static final int MSG_ON_CONFIGURATION_CHANGED = 6;
+    private static final int MSG_DOCK_TOP_TASK = 7;
+    private static final int MSG_ON_DRAGGING_IN_RECENTS = 8;
+    private static final int MSG_ON_DRAGGING_IN_RECENTS_ENDED = 9;
+
+    private RecentsImpl mImpl;
+
+    public RecentsImplProxy(RecentsImpl recentsImpl) {
+        mImpl = recentsImpl;
+    }
+
+    @Override
+    public void preloadRecents() throws RemoteException {
+        mHandler.sendEmptyMessage(MSG_PRELOAD_RECENTS);
+    }
+
+    @Override
+    public void cancelPreloadingRecents() throws RemoteException {
+        mHandler.sendEmptyMessage(MSG_CANCEL_PRELOADING_RECENTS);
+    }
+
+    @Override
+    public void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents, boolean animate,
+            boolean reloadTasks) throws RemoteException {
+        SomeArgs args = SomeArgs.obtain();
+        args.argi1 = triggeredFromAltTab ? 1 : 0;
+        args.argi2 = draggingInRecents ? 1 : 0;
+        args.argi3 = animate ? 1 : 0;
+        args.argi4 = reloadTasks ? 1 : 0;
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_SHOW_RECENTS, args));
+    }
+
+    @Override
+    public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey)
+            throws RemoteException {
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_HIDE_RECENTS, triggeredFromAltTab ? 1 :0,
+                triggeredFromHomeKey ? 1 : 0));
+    }
+
+    @Override
+    public void toggleRecents() throws RemoteException {
+        mHandler.sendEmptyMessage(MSG_TOGGLE_RECENTS);
+    }
+
+    @Override
+    public void onConfigurationChanged() throws RemoteException {
+        mHandler.sendEmptyMessage(MSG_ON_CONFIGURATION_CHANGED);
+    }
+
+    @Override
+    public void dockTopTask(int topTaskId, int dragMode, int stackCreateMode,
+            Rect initialBounds) throws RemoteException {
+        SomeArgs args = SomeArgs.obtain();
+        args.argi1 = topTaskId;
+        args.argi2 = dragMode;
+        args.argi3 = stackCreateMode;
+        args.arg1 = initialBounds;
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_DOCK_TOP_TASK, args));
+    }
+
+    @Override
+    public void onDraggingInRecents(float distanceFromTop) throws RemoteException {
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_DRAGGING_IN_RECENTS, distanceFromTop));
+    }
+
+    @Override
+    public void onDraggingInRecentsEnded(float velocity) throws RemoteException {
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_DRAGGING_IN_RECENTS_ENDED, velocity));
+    }
+
+    private final Handler mHandler = new Handler() {
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_PRELOAD_RECENTS:
+                    mImpl.preloadRecents();
+                    break;
+                case MSG_CANCEL_PRELOADING_RECENTS:
+                    mImpl.cancelPreloadingRecents();
+                    break;
+                case MSG_SHOW_RECENTS:
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    mImpl.showRecents(args.argi1 != 0, args.argi2 != 0, args.argi3 != 0,
+                            args.argi4 != 0);
+                    break;
+                case MSG_HIDE_RECENTS:
+                    mImpl.hideRecents(msg.arg1 != 0, msg.arg2 != 0);
+                    break;
+                case MSG_TOGGLE_RECENTS:
+                    mImpl.toggleRecents();
+                    break;
+                case MSG_ON_CONFIGURATION_CHANGED:
+                    mImpl.onConfigurationChanged();
+                    break;
+                case MSG_DOCK_TOP_TASK:
+                    args = (SomeArgs) msg.obj;
+                    mImpl.dockTopTask(args.argi1, args.argi2, args.argi3 = 0,
+                            (Rect) args.arg1);
+                    break;
+                case MSG_ON_DRAGGING_IN_RECENTS:
+                    mImpl.onDraggingInRecents((Float) msg.obj);
+                    break;
+                case MSG_ON_DRAGGING_IN_RECENTS_ENDED:
+                    mImpl.onDraggingInRecentsEnded((Float) msg.obj);
+                    break;
+                default:
+                    super.handleMessage(msg);
+            }
+            super.handleMessage(msg);
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
index fb21500..ae0051c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
@@ -22,6 +22,11 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.DockingTopTaskEvent;
+import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
+import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
+
 /**
  * An implementation of the system user's Recents interface to be called remotely by secondary
  * users.
@@ -70,4 +75,19 @@
     public void startScreenPinning() {
         mImpl.onStartScreenPinning(mContext);
     }
+
+    @Override
+    public void sendRecentsDrawnEvent() {
+        EventBus.getDefault().post(new RecentsDrawnEvent());
+    }
+
+    @Override
+    public void sendDockingTopTaskEvent(int dragMode) throws RemoteException {
+        EventBus.getDefault().post(new DockingTopTaskEvent(dragMode));
+    }
+
+    @Override
+    public void sendLaunchRecentsEvent() throws RemoteException {
+        EventBus.getDefault().post(new RecentsActivityStartingEvent());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockingTopTaskEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockingTopTaskEvent.java
new file mode 100644
index 0000000..264c2c4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockingTopTaskEvent.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * Fires when the user invoked the gesture to dock the top/left task.
+ */
+public class DockingTopTaskEvent extends EventBus.Event {
+
+    public int dragMode;
+
+    public DockingTopTaskEvent(int dragMode) {
+        this.dragMode = dragMode;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsTaskStackAnimationCompletedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsTaskStackAnimationCompletedEvent.java
new file mode 100644
index 0000000..ee0df87
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsTaskStackAnimationCompletedEvent.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * This is sent when the in-app animations into Recents completes.
+ */
+public class EnterRecentsTaskStackAnimationCompletedEvent extends EventBus.AnimatedEvent {
+    // Simple event
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/RecentsActivityStartingEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/RecentsActivityStartingEvent.java
new file mode 100644
index 0000000..a2ecfe2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/RecentsActivityStartingEvent.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * Called after recents activity is being started, i.e. startActivity has just been called.
+ */
+public class RecentsActivityStartingEvent extends EventBus.Event{
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsDrawnEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsDrawnEvent.java
new file mode 100644
index 0000000..5483166
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsDrawnEvent.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.recents.events.ui;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * Fired when recents was launched and has drawn its first frame.
+ */
+public class RecentsDrawnEvent extends EventBus.Event {
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java
index 5a132c2..39e4c1d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/UserInteractionEvent.java
@@ -21,11 +21,6 @@
 /**
  * This is sent whenever the user interacts with the activity.
  */
-public class UserInteractionEvent extends EventBus.Event {
-
-    public final boolean showTimerIndicator;
-
-    public UserInteractionEvent(boolean showTimerIndicator) {
-        this.showTimerIndicator = showTimerIndicator;
-    }
+public class UserInteractionEvent extends EventBus.ReusableEvent {
+    // Simple Event
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
index def4ae1..a1e4957 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/focus/FocusNextTaskViewEvent.java
@@ -23,9 +23,9 @@
  */
 public class FocusNextTaskViewEvent extends EventBus.Event {
 
-    public final boolean showTimerIndicator;
+    public final int timerIndicatorDuration;
 
-    public FocusNextTaskViewEvent(boolean showTimerIndicator) {
-        this.showTimerIndicator = showTimerIndicator;
+    public FocusNextTaskViewEvent(int timerIndicatorDuration) {
+        this.timerIndicatorDuration = timerIndicatorDuration;
     }
 }
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 f6655c7..4000991 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
@@ -26,7 +26,9 @@
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.events.EventBus;
@@ -132,7 +134,7 @@
             ssp.startActivityFromRecents(v.getContext(), task.key.id, task.title,
                     ActivityOptions.makeBasic());
 
-            MetricsLogger.action(v.getContext(), MetricsLogger.ACTION_OVERVIEW_SELECT,
+            MetricsLogger.action(v.getContext(), MetricsEvent.ACTION_OVERVIEW_SELECT,
                     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 39bb6ca..b9921b6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
@@ -28,7 +28,9 @@
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.LinearLayout;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivity;
@@ -101,7 +103,7 @@
         mAdapter.updateTasks(getContext(), stack);
         mIsVisible = true;
 
-        MetricsLogger.visible(mRecyclerView.getContext(), MetricsLogger.OVERVIEW_HISTORY);
+        MetricsLogger.visible(mRecyclerView.getContext(), MetricsEvent.OVERVIEW_HISTORY);
     }
 
     /**
@@ -133,7 +135,7 @@
         }
         mIsVisible = false;
 
-        MetricsLogger.hidden(mRecyclerView.getContext(), MetricsLogger.OVERVIEW_HISTORY);
+        MetricsLogger.hidden(mRecyclerView.getContext(), MetricsEvent.OVERVIEW_HISTORY);
     }
 
     /**
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 dc8f547..244c0df 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java
@@ -64,6 +64,13 @@
     }
 
     /**
+     * Updates the duration that we have to wait until dozing triggers.
+     */
+    public void setDozeDuration(int duration) {
+        mDozeDurationMilliseconds = duration;
+    }
+
+    /**
      * Poke this dozer to wake it up if it is dozing, delaying the onSleepRunnable from being
      * called for a for the doze duration.
      */
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 3f52ae8..2882cec 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -151,7 +151,7 @@
         // Resolve the assist intent
         mAssistComponent = mAssistUtils.getAssistComponentForUser(UserHandle.myUserId());
 
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
             // Create a dummy icon
             mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
             mDummyIcon.eraseColor(0xFF999999);
@@ -164,20 +164,20 @@
         if (mAm == null) return null;
 
         // If we are mocking, then create some recent tasks
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
             ArrayList<ActivityManager.RecentTaskInfo> tasks =
                     new ArrayList<ActivityManager.RecentTaskInfo>();
-            int count = Math.min(numLatestTasks, RecentsDebugFlags.Static.SystemServicesProxyMockTaskCount);
+            int count = Math.min(numLatestTasks, RecentsDebugFlags.Static.MockTaskCount);
             for (int i = 0; i < count; i++) {
                 // Create a dummy component name
-                int packageIndex = i % RecentsDebugFlags.Static.SystemServicesProxyMockPackageCount;
+                int packageIndex = i % RecentsDebugFlags.Static.MockTasksPackageCount;
                 ComponentName cn = new ComponentName("com.android.test" + packageIndex,
                         "com.android.test" + i + ".Activity");
                 String description = "" + i + " - " +
                         Long.toString(Math.abs(new Random().nextLong()), 36);
                 // Create the recent task info
                 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
-                rti.id = rti.persistentId = i;
+                rti.id = rti.persistentId = rti.affiliatedTaskId = i;
                 rti.baseIntent = new Intent();
                 rti.baseIntent.setComponent(cn);
                 rti.description = description;
@@ -378,13 +378,19 @@
         ActivityManager.StackInfo stackInfo = null;
         try {
             stackInfo = mIam.getStackInfo(DOCKED_STACK_ID);
-            if (stackInfo != null && stackInfo.userId != getCurrentUser()) {
-                return false;
-            }
         } catch (RemoteException e) {
             e.printStackTrace();
         }
-        return stackInfo != null;
+
+        if (stackInfo != null) {
+            int userId = getCurrentUser();
+            boolean hasUserTask = false;
+            for (int i = stackInfo.taskUserIds.length - 1; i >= 0 && !hasUserTask; i--) {
+                hasUserTask = (stackInfo.taskUserIds[i] == userId);
+            }
+            return hasUserTask;
+        }
+        return false;
     }
 
     /**
@@ -418,7 +424,7 @@
         if (mAm == null) return null;
 
         // If we are mocking, then just return a dummy thumbnail
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
             Bitmap thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth, mDummyThumbnailHeight,
                     Bitmap.Config.ARGB_8888);
             thumbnail.eraseColor(0xff333333);
@@ -484,7 +490,7 @@
     /** Moves a task to the front with the specified activity options. */
     public void moveTaskToFront(int taskId, ActivityOptions opts) {
         if (mAm == null) return;
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return;
+        if (RecentsDebugFlags.Static.EnableMockTasks) return;
 
         if (opts != null) {
             mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME,
@@ -497,7 +503,7 @@
     /** Removes the task */
     public void removeTask(final int taskId) {
         if (mAm == null) return;
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return;
+        if (RecentsDebugFlags.Static.EnableMockTasks) return;
 
         // Remove the task.
         BackgroundThread.getHandler().post(new Runnable() {
@@ -528,7 +534,7 @@
      */
     public ActivityInfo getActivityInfo(ComponentName cn, int userId) {
         if (mIpm == null) return null;
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return new ActivityInfo();
+        if (RecentsDebugFlags.Static.EnableMockTasks) return new ActivityInfo();
 
         try {
             return mIpm.getActivityInfo(cn, PackageManager.GET_META_DATA, userId);
@@ -545,7 +551,7 @@
      */
     public ActivityInfo getActivityInfo(ComponentName cn) {
         if (mPm == null) return null;
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return new ActivityInfo();
+        if (RecentsDebugFlags.Static.EnableMockTasks) return new ActivityInfo();
 
         try {
             return mPm.getActivityInfo(cn, PackageManager.GET_META_DATA);
@@ -562,7 +568,7 @@
         if (mPm == null) return null;
 
         // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
             return "Recent Task: " + userId;
         }
 
@@ -576,7 +582,7 @@
         if (mPm == null) return null;
 
         // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
             return "Recent Task App: " + userId;
         }
 
@@ -588,6 +594,11 @@
      * description joins the app and activity labels.
      */
     public String getBadgedContentDescription(ActivityInfo info, int userId, Resources res) {
+        // If we are mocking, then return a mock label
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
+            return "Recent Task Content Description: " + userId;
+        }
+
         String activityLabel = info.loadLabel(mPm).toString();
         String applicationLabel = info.applicationInfo.loadLabel(mPm).toString();
         String badgedApplicationLabel = getBadgedLabel(applicationLabel, userId);
@@ -604,7 +615,7 @@
         if (mPm == null) return null;
 
         // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
             return new ColorDrawable(0xFF666666);
         }
 
@@ -620,7 +631,7 @@
         if (mPm == null) return null;
 
         // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
             return new ColorDrawable(0xFF666666);
         }
 
@@ -635,7 +646,7 @@
             int userId, Resources res) {
 
         // If we are mocking, then return a mock label
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
             return new ColorDrawable(0xFF666666);
         }
 
@@ -673,7 +684,7 @@
     /** Returns the package name of the home activity. */
     public String getHomeActivityPackageName() {
         if (mPm == null) return null;
-        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) return null;
+        if (RecentsDebugFlags.Static.EnableMockTasks) return null;
 
         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
         ComponentName defaultHomeActivity = mPm.getHomeActivities(homeActivities);
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 9cdd703..d15828a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -22,6 +22,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
+import android.os.Debug;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.ArraySet;
@@ -31,6 +32,7 @@
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 
 import java.util.ArrayList;
@@ -130,6 +132,9 @@
                 R.string.accessibility_recents_item_will_be_dismissed);
         long lastStackActiveTime = Prefs.getLong(mContext,
                 Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, 0);
+        if (RecentsDebugFlags.Static.EnableMockTasks) {
+            lastStackActiveTime = 0;
+        }
         long newLastStackActiveTime = -1;
         int taskCount = mRawTasks.size();
         for (int i = 0; i < taskCount; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index de1daa8..66eeac6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -776,7 +776,7 @@
      * Temporary: This method will simulate affiliation groups by
      */
     public void createAffiliatedGroupings(Context context) {
-        if (RecentsDebugFlags.Static.EnableSimulatedTaskGroups) {
+        if (RecentsDebugFlags.Static.EnableMockTaskGroups) {
             ArrayMap<Task.TaskKey, Task> taskMap = new ArrayMap<>();
             // Sort all tasks by increasing firstActiveTime of the task
             ArrayList<Task> tasks = mStackTaskList.getTasks();
@@ -792,7 +792,7 @@
             String prevPackage = "";
             int prevAffiliation = -1;
             Random r = new Random();
-            int groupCountDown = RecentsDebugFlags.Static.TaskAffiliationsGroupCount;
+            int groupCountDown = RecentsDebugFlags.Static.MockTaskGroupsTaskCount;
             for (int i = 0; i < taskCount; i++) {
                 Task t = tasks.get(i);
                 String packageName = t.key.getComponent().getPackageName();
@@ -807,7 +807,7 @@
                     addGroup(group);
                     prevAffiliation = affiliation;
                     prevPackage = packageName;
-                    groupCountDown = RecentsDebugFlags.Static.TaskAffiliationsGroupCount;
+                    groupCountDown = RecentsDebugFlags.Static.MockTaskGroupsTaskCount;
                 }
                 group.addTask(t);
                 taskMap.put(t.key, t);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeFrameLayout.java b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeFrameLayout.java
new file mode 100644
index 0000000..9f2b00a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeFrameLayout.java
@@ -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.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+/**
+ * This is an optimized FrameLayout whose layout is completely directed by its parent, and as a
+ * result, does not propagate <code>requestLayout()</code> up the view hierarchy. Instead, it will
+ * relayout its children with the last known layout bounds when a layout is requested from a child
+ * view.
+ */
+public class FixedSizeFrameLayout extends FrameLayout {
+
+    private final Rect mLayoutBounds = new Rect();
+
+    public FixedSizeFrameLayout(Context context) {
+        super(context);
+    }
+
+    public FixedSizeFrameLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public FixedSizeFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public FixedSizeFrameLayout(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected final void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        measureContents(MeasureSpec.getSize(widthMeasureSpec),
+                MeasureSpec.getSize(heightMeasureSpec));
+    }
+
+    @Override
+    protected final void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        mLayoutBounds.set(left, top, right, bottom);
+        layoutContents(mLayoutBounds, changed);
+    }
+
+    @Override
+    public final void requestLayout() {
+        // The base ViewGroup constructor attempts to call requestLayout() before this class's
+        // members are initialized so we should just propagate in that case
+        if (mLayoutBounds == null || mLayoutBounds.isEmpty()) {
+            super.requestLayout();
+        } else {
+            // If we are already laid out, then just reuse the same bounds to layout the children
+            // (but not itself)
+            // TODO: Investigate whether we should coalesce these to the next frame if needed
+            measureContents(getMeasuredWidth(), getMeasuredHeight());
+            layoutContents(mLayoutBounds, false);
+        }
+    }
+
+    /**
+     * Measures the contents of this fixed layout.
+     */
+    protected void measureContents(int width, int height) {
+        super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
+                MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
+    }
+
+    /**
+     * Lays out the contents of this fixed layout.
+     */
+    protected void layoutContents(Rect bounds, boolean changed) {
+        super.onLayout(changed, bounds.left, bounds.top, bounds.right, bounds.bottom);
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java
index 3f5d0a8..f5ab01f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FixedSizeImageView.java
@@ -23,13 +23,13 @@
 import android.widget.ImageView;
 
 /**
- * This is an optimized ImageView that does not trigger a requestLayout() or invalidate() when
- * setting the image to Null.
+ * This is an optimized ImageView that does not trigger a <code>requestLayout()</code> or
+ * <code>invalidate()</code> when setting the image to <code>null</code>.
  */
 public class FixedSizeImageView extends ImageView {
 
-    boolean mAllowRelayout = true;
-    boolean mAllowInvalidate = true;
+    private boolean mAllowRelayout = true;
+    private boolean mAllowInvalidate = true;
 
     public FixedSizeImageView(Context context) {
         this(context, null);
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 e448101..a00b497 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -34,7 +34,9 @@
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 import android.widget.TextView;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivity;
@@ -537,8 +539,7 @@
                                 }
                             }));
 
-            MetricsLogger.action(mContext,
-                    MetricsLogger.ACTION_WINDOW_DOCK_DRAG_DROP);
+            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP);
         } else {
             // Animate the overlay alpha back to 0
             updateVisibleDockRegions(null, true /* isDefaultDockState */, -1,
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 e99509c..93849dc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -110,6 +110,10 @@
     public static final float STATE_FOCUSED = 1f;
     public static final float STATE_UNFOCUSED = 0f;
 
+    public interface TaskStackLayoutAlgorithmCallbacks {
+        void onFocusStateChanged(float prevFocusState, float curFocusState);
+    }
+
     /**
      * The various stack/freeform states.
      */
@@ -210,6 +214,7 @@
     Context mContext;
     private Interpolator mLinearOutSlowInInterpolator;
     private StackState mState = StackState.SPLIT;
+    private TaskStackLayoutAlgorithmCallbacks mCb;
 
     // The task bounds (untransformed) for layout.  This rect is anchored at mTaskRoot.
     public Rect mTaskRect = new Rect();
@@ -279,8 +284,10 @@
     TaskViewTransform mBackOfStackTransform = new TaskViewTransform();
     TaskViewTransform mFrontOfStackTransform = new TaskViewTransform();
 
-    public TaskStackLayoutAlgorithm(Context context) {
+    public TaskStackLayoutAlgorithm(Context context, TaskStackLayoutAlgorithmCallbacks cb) {
         Resources res = context.getResources();
+        mContext = context;
+        mCb = cb;
 
         mFocusedRange = new Range(res.getFloat(R.integer.recents_layout_focused_range_min),
                 res.getFloat(R.integer.recents_layout_focused_range_max));
@@ -291,7 +298,6 @@
 
         mMinTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
         mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_max);
-        mContext = context;
         mFreeformLayoutAlgorithm = new FreeformWorkspaceLayoutAlgorithm(context);
         mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.linear_out_slow_in);
@@ -315,8 +321,12 @@
      * Sets the focused state.
      */
     public void setFocusState(float focusState) {
+        float prevFocusState = mFocusState;
         mFocusState = focusState;
         updateFrontBackTransforms();
+        if (mCb != null) {
+            mCb.onFocusStateChanged(prevFocusState, focusState);
+        }
     }
 
     /**
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 de045f4..7423b78 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -44,9 +44,11 @@
 import com.android.systemui.recents.RecentsActivity;
 import com.android.systemui.recents.RecentsActivityLaunchState;
 import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
+import com.android.systemui.recents.events.activity.EnterRecentsTaskStackAnimationCompletedEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
 import com.android.systemui.recents.events.activity.HideHistoryButtonEvent;
 import com.android.systemui.recents.events.activity.HideHistoryEvent;
@@ -88,6 +90,7 @@
 /* The visual representation of a task stack view */
 public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCallbacks,
         TaskView.TaskViewCallbacks, TaskStackViewScroller.TaskStackViewScrollerCallbacks,
+        TaskStackLayoutAlgorithm.TaskStackLayoutAlgorithmCallbacks,
         ViewPool.ViewPoolConsumer<TaskView, Task> {
 
     private final static String KEY_SAVED_STATE_SUPER = "saved_instance_state_super";
@@ -114,7 +117,6 @@
     GradientDrawable mFreeformWorkspaceBackground;
     ObjectAnimator mFreeformWorkspaceBackgroundAnimator;
     ViewPool<TaskView, Task> mViewPool;
-    boolean mStartTimerIndicator;
 
     ArrayList<TaskView> mTaskViews = new ArrayList<>();
     ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
@@ -126,6 +128,7 @@
 
     int mTaskCornerRadiusPx;
     private int mDividerSize;
+    private int mStartTimerIndicatorDuration;
 
     boolean mTaskViewsClipDirty = true;
     boolean mAwaitingFirstLayout = true;
@@ -192,9 +195,8 @@
         setStack(stack);
         mViewPool = new ViewPool<>(context, this);
         mInflater = LayoutInflater.from(context);
-        mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context);
-        mStackScroller = new TaskStackViewScroller(context, mLayoutAlgorithm);
-        mStackScroller.setCallbacks(this);
+        mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this);
+        mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
         mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
         mAnimationHelper = new TaskStackAnimationHelper(context, this);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -623,7 +625,7 @@
      */
     void relayoutTaskViewsOnNextFrame(TaskViewAnimation animation) {
         mDeferredTaskViewLayoutAnimation = animation;
-        postInvalidateOnAnimation();
+        invalidate();
     }
 
     /**
@@ -796,7 +798,7 @@
      */
     private boolean setFocusedTask(int taskIndex, boolean scrollToTask,
             final boolean requestViewFocus) {
-        return setFocusedTask(taskIndex, scrollToTask, requestViewFocus, false);
+        return setFocusedTask(taskIndex, scrollToTask, requestViewFocus, 0);
     }
 
     /**
@@ -805,7 +807,7 @@
      * @return whether or not the stack will scroll as a part of this focus change
      */
     private boolean setFocusedTask(int taskIndex, boolean scrollToTask,
-            final boolean requestViewFocus, final boolean showTimerIndicator) {
+            final boolean requestViewFocus, final int timerIndicatorDuration) {
         // Find the next task to focus
         int newFocusedTaskIndex = mStack.getTaskCount() > 0 ?
                 Math.max(0, Math.min(mStack.getTaskCount() - 1, taskIndex)) : -1;
@@ -815,7 +817,7 @@
         // Reset the last focused task state if changed
         if (mFocusedTask != null) {
             // Cancel the timer indicator, if applicable
-            if (showTimerIndicator) {
+            if (timerIndicatorDuration > 0) {
                 final TaskView tv = getChildViewForTask(mFocusedTask);
                 if (tv != null) {
                     tv.getHeaderView().cancelFocusTimerIndicator();
@@ -831,13 +833,13 @@
 
         if (newFocusedTask != null) {
             // Start the timer indicator, if applicable
-            if (showTimerIndicator) {
+            if (timerIndicatorDuration > 0) {
                 final TaskView tv = getChildViewForTask(mFocusedTask);
                 if (tv != null) {
-                    tv.getHeaderView().startFocusTimerIndicator();
+                    tv.getHeaderView().startFocusTimerIndicator(timerIndicatorDuration);
                 } else {
                     // The view is null; set a flag for later
-                    mStartTimerIndicator = true;
+                    mStartTimerIndicatorDuration = timerIndicatorDuration;
                 }
             }
 
@@ -852,17 +854,17 @@
             };
 
             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(mStackScroller.getStackScroll(), newScroll,
                             focusTaskRunnable);
                     willScroll = true;
-
-                    // Cancel any running enter animations at this point when we scroll as well
-                    if (!mEnterAnimationComplete) {
-                        cancelAllTaskViewAnimations();
-                    }
                 } else {
                     focusTaskRunnable.run();
                 }
@@ -902,7 +904,7 @@
      */
     public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
                                        boolean cancelWindowAnimations) {
-        setRelativeFocusedTask(forward, stackTasksOnly, animated, false, false);
+        setRelativeFocusedTask(forward, stackTasksOnly, animated, cancelWindowAnimations, 0);
     }
 
     /**
@@ -916,10 +918,11 @@
      *                            focus.
      * @param cancelWindowAnimations if set, will attempt to cancel window animations if a scroll
      *                               happens.
-     * @param showTimerIndicator determines whether or not to show an indicator for the task auto-advance.
+     * @param timerIndicatorDuration the duration to initialize the auto-advance timer indicator
      */
     public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
-                                       boolean cancelWindowAnimations, boolean showTimerIndicator) {
+                                       boolean cancelWindowAnimations,
+                                       int timerIndicatorDuration) {
         int newIndex = mStack.indexOfStackTask(mFocusedTask);
         if (mFocusedTask != null) {
             if (stackTasksOnly) {
@@ -955,7 +958,7 @@
         }
         if (newIndex != -1) {
             boolean willScroll = setFocusedTask(newIndex, true /* scrollToTask */,
-                    true /* requestViewFocus */, showTimerIndicator);
+                    true /* requestViewFocus */, timerIndicatorDuration);
             if (willScroll && cancelWindowAnimations) {
                 // As we iterate to the next/previous task, cancel any current/lagging window
                 // transition animations
@@ -1223,9 +1226,7 @@
         Task launchTask = mStack.getLaunchTarget();
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
-        int focusedTaskIndex = launchTask != null
-                ? mStack.indexOfStackTask(launchTask)
-                : launchState.getInitialFocusTaskIndex(mStack.getTaskCount());
+        int focusedTaskIndex = launchState.getInitialFocusTaskIndex(mStack.getTaskCount());
         if (focusedTaskIndex != -1) {
             setFocusedTask(focusedTaskIndex, false /* scrollToTask */,
                     false /* requestViewFocus */);
@@ -1375,11 +1376,6 @@
         // Report that this tasks's data is no longer being used
         Recents.getTaskLoader().unloadTaskData(task);
 
-        // Detach the view from the hierarchy
-        detachViewFromParent(tv);
-        // Update the task views list after removing the task view
-        updateTaskViewsList();
-
         // Reset the view properties and view state
         tv.resetViewProperties();
         tv.setFocusedState(false, false /* requestViewFocus */);
@@ -1387,19 +1383,15 @@
         if (mScreenPinningEnabled) {
             tv.hideActionButton(false /* fadeOut */, 0 /* duration */, false /* scaleDown */, null);
         }
+
+        // Detach the view from the hierarchy
+        detachViewFromParent(tv);
+        // Update the task views list after removing the task view
+        updateTaskViewsList();
     }
 
     @Override
     public void prepareViewToLeavePool(TaskView tv, Task task, boolean isNewView) {
-        // Rebind the task and request that this task's data be filled into the TaskView
-        tv.onTaskBound(task);
-
-        // Load the task data
-        Recents.getTaskLoader().loadTaskData(task);
-
-        // If the doze trigger has already fired, then update the state for this task view
-        tv.setNoUserInteractionState();
-
         // Find the index where this task should be placed in the stack
         int taskIndex = mStack.indexOfStackTask(task);
         int insertIndex = findTaskViewInsertIndex(task, taskIndex);
@@ -1413,16 +1405,25 @@
         // Update the task views list after adding the new task view
         updateTaskViewsList();
 
+        // Rebind the task and request that this task's data be filled into the TaskView
+        tv.onTaskBound(task);
+
+        // Load the task data
+        Recents.getTaskLoader().loadTaskData(task);
+
+        // If the doze trigger has already fired, then update the state for this task view
+        tv.setNoUserInteractionState();
+
         // Set the new state for this view, including the callbacks and view clipping
         tv.setCallbacks(this);
         tv.setTouchEnabled(true);
         tv.setClipViewInStack(true);
         if (mFocusedTask == task) {
             tv.setFocusedState(true, false /* requestViewFocus */);
-            if (mStartTimerIndicator) {
+            if (mStartTimerIndicatorDuration > 0) {
                 // The timer indicator couldn't be started before, so start it now
-                tv.getHeaderView().startFocusTimerIndicator();
-                mStartTimerIndicator = false;
+                tv.getHeaderView().startFocusTimerIndicator(mStartTimerIndicatorDuration);
+                mStartTimerIndicatorDuration = 0;
             }
         }
 
@@ -1448,6 +1449,16 @@
         }
     }
 
+    /**** TaskStackLayoutAlgorithm.TaskStackLayoutAlgorithmCallbacks ****/
+
+    @Override
+    public void onFocusStateChanged(float prevFocusState, float curFocusState) {
+        if (mDeferredTaskViewLayoutAnimation == null) {
+            mUIDozeTrigger.poke();
+            relayoutTaskViewsOnNextFrame(TaskViewAnimation.IMMEDIATE);
+        }
+    }
+
     /**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/
 
     @Override
@@ -1539,7 +1550,7 @@
 
     public final void onBusEvent(FocusNextTaskViewEvent event) {
         setRelativeFocusedTask(true, false /* stackTasksOnly */, true /* animated */, false,
-                event.showTimerIndicator);
+                event.timerIndicatorDuration);
     }
 
     public final void onBusEvent(FocusPreviousTaskViewEvent event) {
@@ -1549,7 +1560,9 @@
     public final void onBusEvent(UserInteractionEvent event) {
         // Poke the doze trigger on user interaction
         mUIDozeTrigger.poke();
-        if (event.showTimerIndicator && mFocusedTask != null) {
+
+        RecentsDebugFlags debugFlags = Recents.getDebugFlags();
+        if (debugFlags.isFastToggleRecentsEnabled() && mFocusedTask != null) {
             TaskView tv = getChildViewForTask(mFocusedTask);
             if (tv != null) {
                 tv.getHeaderView().cancelFocusTimerIndicator();
@@ -1705,11 +1718,28 @@
                         setFocusedTask(mStack.indexOfStackTask(mFocusedTask),
                                 false /* scrollToTask */, launchState.launchedWithAltTab);
                     }
+
+                    EventBus.getDefault().send(new EnterRecentsTaskStackAnimationCompletedEvent());
                 }
             });
         }
     }
 
+    public final void onBusEvent(EnterRecentsTaskStackAnimationCompletedEvent event) {
+        RecentsDebugFlags debugFlags = Recents.getDebugFlags();
+        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
+        if (!launchState.launchedWithAltTab && debugFlags.isFastToggleRecentsEnabled() &&
+                RecentsDebugFlags.Static.EnableFastToggleTimeoutOnEnter) {
+            if (mFocusedTask != null) {
+                int timerIndicatorDuration = getResources().getInteger(
+                        R.integer.recents_auto_advance_duration);
+                int focusedTaskIndex = mStack.indexOfStackTask(mFocusedTask);
+                setFocusedTask(focusedTaskIndex, false /* scrollToTask */,
+                        false /* requestViewFocus */, timerIndicatorDuration);
+            }
+        }
+    }
+
     public final void onBusEvent(UpdateFreeformTaskViewVisibilityEvent event) {
         List<TaskView> taskViews = getTaskViews();
         int taskViewCount = taskViews.size();
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 5335b14..4ec051f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
@@ -20,7 +20,9 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.util.FloatProperty;
 import android.util.Log;
+import android.util.Property;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.OverScroller;
@@ -37,6 +39,24 @@
         void onScrollChanged(float prevScroll, float curScroll, TaskViewAnimation animation);
     }
 
+    /**
+     * A Property wrapper around the <code>stackScroll</code> functionality handled by the
+     * {@link #setStackScroll(float)} and
+     * {@link #getStackScroll()} methods.
+     */
+    private static final Property<TaskStackViewScroller, Float> STACK_SCROLL =
+            new FloatProperty<TaskStackViewScroller>("stackScroll") {
+                @Override
+                public void setValue(TaskStackViewScroller object, float value) {
+                    object.setStackScroll(value);
+                }
+
+                @Override
+                public Float get(TaskStackViewScroller object) {
+                    return object.getStackScroll();
+                }
+            };
+
     Context mContext;
     TaskStackLayoutAlgorithm mLayoutAlgorithm;
     TaskStackViewScrollerCallbacks mCb;
@@ -51,8 +71,10 @@
 
     private Interpolator mLinearOutSlowInInterpolator;
 
-    public TaskStackViewScroller(Context context, TaskStackLayoutAlgorithm layoutAlgorithm) {
+    public TaskStackViewScroller(Context context, TaskStackViewScrollerCallbacks cb,
+            TaskStackLayoutAlgorithm layoutAlgorithm) {
         mContext = context;
+        mCb = cb;
         mScroller = new OverScroller(context);
         mLayoutAlgorithm = layoutAlgorithm;
         mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -64,11 +86,6 @@
         mStackScrollP = 0f;
     }
 
-    /** Sets the callbacks */
-    void setCallbacks(TaskStackViewScrollerCallbacks cb) {
-        mCb = cb;
-    }
-
     /** Gets the current stack scroll */
     public float getStackScroll() {
         return mStackScrollP;
@@ -172,7 +189,7 @@
         stopBoundScrollAnimation();
 
         mFinalAnimatedScroll = newScroll;
-        mScrollAnimator = ObjectAnimator.ofFloat(this, "stackScroll", curScroll, newScroll);
+        mScrollAnimator = ObjectAnimator.ofFloat(this, STACK_SCROLL, curScroll, newScroll);
         mScrollAnimator.setDuration(mContext.getResources().getInteger(
                 R.integer.recents_animate_task_stack_scroll_duration));
         mScrollAnimator.setInterpolator(mLinearOutSlowInInterpolator);
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 32bebb3..5a4064a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -17,7 +17,6 @@
 package com.android.systemui.recents.views;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
@@ -40,7 +39,6 @@
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
-import android.widget.FrameLayout;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivity;
@@ -62,8 +60,13 @@
 
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 
-/* A task view */
-public class TaskView extends FrameLayout implements Task.TaskCallbacks,
+/**
+ * A {@link TaskView} represents a fixed view of a task. Because the TaskView's layout is directed
+ * solely by the {@link TaskStackView}, we make it a fixed size layout which allows relayouts down
+ * the view hierarchy, but not upwards from any of its children (the TaskView will relayout itself
+ * with the previous bounds if any child requests layout).
+ */
+public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks,
         TaskStackAnimationHelper.Callbacks, View.OnClickListener, View.OnLongClickListener {
 
     /** The TaskView callbacks */
@@ -219,33 +222,20 @@
         return super.onInterceptTouchEvent(ev);
     }
 
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int width = MeasureSpec.getSize(widthMeasureSpec);
-        int height = MeasureSpec.getSize(heightMeasureSpec);
 
+    @Override
+    protected void measureContents(int width, int height) {
         int widthWithoutPadding = width - mPaddingLeft - mPaddingRight;
         int heightWithoutPadding = height - mPaddingTop - mPaddingBottom;
-        int taskBarHeight = getResources().getDimensionPixelSize(R.dimen.recents_task_bar_height);
 
         // Measure the content
         mContent.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
                 MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.EXACTLY));
 
-        // Measure the bar view, and action button
-        mHeaderView.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
-                MeasureSpec.makeMeasureSpec(taskBarHeight, MeasureSpec.EXACTLY));
-        mActionButtonView.measure(
-                MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.AT_MOST),
-                MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.AT_MOST));
-        // Measure the thumbnail to be square
-        mThumbnailView.measure(
-                MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
-                MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.EXACTLY));
+        // Optimization: Prevent overdraw of the thumbnail under the header view
         mThumbnailView.updateClipToTaskBar(mHeaderView);
 
         setMeasuredDimension(width, height);
-        invalidateOutline();
     }
 
     void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform,
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 827ee40..d5aea9d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -169,7 +169,6 @@
     Interpolator mLinearOutSlowInInterpolator;
 
     private CountDownTimer mFocusTimerCountDown;
-    private long mFocusTimerDuration;
 
     public TaskViewHeader(Context context) {
         this(context, null);
@@ -216,7 +215,6 @@
         mOverlayBackground = new HighlightColorDrawable();
         mDimLayerPaint.setColor(Color.argb(255, 0, 0, 0));
         mDimLayerPaint.setAntiAlias(true);
-        mFocusTimerDuration = res.getInteger(R.integer.recents_auto_advance_duration);
     }
 
     /**
@@ -245,11 +243,7 @@
      * to match the frame changes.
      */
     public void onTaskViewSizeChanged(int width, int height) {
-        // Return early if the bounds have not changed
-        if (mTaskViewRect.width() == width && mTaskViewRect.height() == height) {
-            return;
-        }
-
+        // TODO: Optimize this path
         mTaskViewRect.set(0, 0, width, height);
         boolean updateMoveTaskButton = mMoveTaskButton.getVisibility() != View.GONE;
         boolean isFreeformTask = (mTask != null) && mTask.isFreeformTask();
@@ -308,27 +302,27 @@
     }
 
     /** Starts the focus timer. */
-    public void startFocusTimerIndicator() {
+    public void startFocusTimerIndicator(int duration) {
         if (mFocusTimerIndicator == null) {
             return;
         }
 
         mFocusTimerIndicator.setVisibility(View.VISIBLE);
-        mFocusTimerIndicator.setMax((int) mFocusTimerDuration);
-        if (mFocusTimerCountDown == null) {
-            mFocusTimerCountDown = new CountDownTimer(mFocusTimerDuration,
-                    FOCUS_INDICATOR_INTERVAL_MS) {
-                public void onTick(long millisUntilFinished) {
-                    mFocusTimerIndicator.setProgress((int) millisUntilFinished);
-                }
-
-                public void onFinish() {
-                    mFocusTimerIndicator.setProgress((int) mFocusTimerDuration);
-                }
-            }.start();
-        } else {
-            mFocusTimerCountDown.start();
+        mFocusTimerIndicator.setMax(duration);
+        mFocusTimerIndicator.setProgress(duration);
+        if (mFocusTimerCountDown != null) {
+            mFocusTimerCountDown.cancel();
         }
+        mFocusTimerCountDown = new CountDownTimer(duration,
+                FOCUS_INDICATOR_INTERVAL_MS) {
+            public void onTick(long millisUntilFinished) {
+                mFocusTimerIndicator.setProgress((int) millisUntilFinished);
+            }
+
+            public void onFinish() {
+                // Do nothing
+            }
+        }.start();
     }
 
     /** Cancels the focus timer. */
@@ -415,7 +409,7 @@
             mMoveTaskButton.setOnClickListener(this);
         }
 
-        if (Recents.getDebugFlags().isFastToggleIndicatorEnabled()) {
+        if (Recents.getDebugFlags().isFastToggleRecentsEnabled()) {
             if (mFocusTimerIndicator == null) {
                 mFocusTimerIndicator = (ProgressBar) mFocusTimerIndicatorStub.inflate();
             }
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 39d0604..de96d9d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -190,7 +190,6 @@
             if (!mInvisible) {
                 updateThumbnailPaintFilter();
             }
-            invalidate();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 77c27fa..d5131be 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -31,6 +31,7 @@
 import android.widget.ImageView;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 
 import java.util.ArrayList;
 
@@ -205,7 +206,7 @@
         if (!mAutomatic) {
             final int val = value + mMinimumBacklight;
             if (stopTracking) {
-                MetricsLogger.action(mContext, MetricsLogger.ACTION_BRIGHTNESS, val);
+                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS, val);
             }
             setBrightness(val);
             if (!tracking) {
@@ -220,7 +221,7 @@
         } else {
             final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1;
             if (stopTracking) {
-                MetricsLogger.action(mContext, MetricsLogger.ACTION_BRIGHTNESS_AUTO, value);
+                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_AUTO, value);
             }
             setBrightnessAdj(adj);
             if (!tracking) {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index cef4d34..4952234 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -25,6 +25,7 @@
 import android.widget.ImageView;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 
 /** A dialog that provides controls for adjusting the screen brightness. */
@@ -53,13 +54,13 @@
     protected void onStart() {
         super.onStart();
         mBrightnessController.registerCallbacks();
-        MetricsLogger.visible(this, MetricsLogger.BRIGHTNESS_DIALOG);
+        MetricsLogger.visible(this, MetricsEvent.BRIGHTNESS_DIALOG);
     }
 
     @Override
     protected void onStop() {
         super.onStop();
-        MetricsLogger.hidden(this, MetricsLogger.BRIGHTNESS_DIALOG);
+        MetricsLogger.hidden(this, MetricsEvent.BRIGHTNESS_DIALOG);
         mBrightnessController.unregisterCallbacks();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 9e83dcf..c0e1e44 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -44,13 +44,17 @@
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
-import android.widget.ImageButton;
 
 import com.android.internal.policy.DividerSnapAlgorithm;
 import com.android.internal.policy.DockedDividerUtils;
 import com.android.systemui.R;
 import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.DockingTopTaskEvent;
+import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
+import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
 import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
 
 import static android.view.PointerIcon.STYLE_HORIZONTAL_DOUBLE_ARROW;
 import static android.view.PointerIcon.STYLE_VERTICAL_DOUBLE_ARROW;
@@ -72,6 +76,18 @@
     private static final float DIM_START_FRACTION = 0.5f;
     private static final float DIM_DAMP_FACTOR = 1.7f;
 
+    /**
+     * Fraction of the divider position between two snap targets to switch to the full-screen
+     * target.
+     */
+    private static final float SWITCH_FULLSCREEN_FRACTION = 0.12f;
+
+    /**
+     * Fraction of the divider position between two snap targets to switch to the larger target
+     * for the bottom/right app layout.
+     */
+    private static final float BOTTOM_RIGHT_SWITCH_BIGGER_FRACTION = 0.2f;
+
     private static final PathInterpolator SLOWDOWN_INTERPOLATOR =
             new PathInterpolator(0.5f, 1f, 0.5f, 1f);
 
@@ -107,6 +123,10 @@
     private DividerSnapAlgorithm mSnapAlgorithm;
     private final Rect mStableInsets = new Rect();
 
+    private boolean mAnimateAfterRecentsDrawn;
+    private boolean mGrowAfterRecentsDrawn;
+    private boolean mGrowRecents;
+
     public DividerView(Context context) {
         super(context);
     }
@@ -137,6 +157,7 @@
         mDividerSize = mDividerWindowWidth - 2 * mDividerInsets;
         mTouchElevation = getResources().getDimensionPixelSize(
                 R.dimen.docked_stack_divider_lift_elevation);
+        mGrowRecents = getResources().getBoolean(R.bool.recents_grow_in_multiwindow);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
                 android.R.interpolator.fast_out_slow_in);
         mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
@@ -150,6 +171,18 @@
     }
 
     @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        EventBus.getDefault().register(this);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        EventBus.getDefault().unregister(this);
+    }
+
+    @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
         mStableInsets.set(insets.getStableInsetLeft(), insets.getStableInsetTop(),
                 insets.getStableInsetRight(), insets.getStableInsetBottom());
@@ -164,15 +197,18 @@
         return mWindowManagerProxy;
     }
 
-    public boolean startDragging(boolean animate) {
-        mHandle.setTouching(true, animate);
+    public boolean startDragging(boolean animate, boolean touching) {
+        if (touching) {
+            mHandle.setTouching(true, animate);
+        }
         mDockSide = mWindowManagerProxy.getDockSide();
-        mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth,
-                mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets);
+        getSnapAlgorithm();
         if (mDockSide != WindowManager.DOCKED_INVALID) {
             mWindowManagerProxy.setResizing(true);
             mWindowManager.setSlippery(false);
-            liftBackground();
+            if (touching) {
+                liftBackground();
+            }
             return true;
         } else {
             return false;
@@ -186,10 +222,31 @@
         releaseBackground();
     }
 
+    public void stopDragging(int position, SnapTarget target, long duration,
+            Interpolator interpolator) {
+        mHandle.setTouching(false, true /* animate */);
+        flingTo(position, target, duration, interpolator);
+        mWindowManager.setSlippery(true);
+        releaseBackground();
+    }
+
     public DividerSnapAlgorithm getSnapAlgorithm() {
+        if (mSnapAlgorithm == null) {
+            mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth,
+                    mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets);
+        }
         return mSnapAlgorithm;
     }
 
+    public int getCurrentPosition() {
+        getLocationOnScreen(mTempInt2);
+        if (isHorizontalDivision()) {
+            return mTempInt2[1] + mDividerInsets;
+        } else {
+            return mTempInt2[0] + mDividerInsets;
+        }
+    }
+
     @Override
     public boolean onTouch(View v, MotionEvent event) {
         convertToScreenCoordinates(event);
@@ -200,13 +257,8 @@
                 mVelocityTracker.addMovement(event);
                 mStartX = (int) event.getX();
                 mStartY = (int) event.getY();
-                getLocationOnScreen(mTempInt2);
-                boolean result = startDragging(true /* animate */);
-                if (isHorizontalDivision()) {
-                    mStartPosition = mTempInt2[1] + mDividerInsets;
-                } else {
-                    mStartPosition = mTempInt2[0] + mDividerInsets;
-                }
+                boolean result = startDragging(true /* animate */, true /* touching */);
+                mStartPosition = getCurrentPosition();
                 mMoving = false;
                 return result;
             case MotionEvent.ACTION_MOVE:
@@ -254,8 +306,20 @@
         if (avoidDismissStart && snapTarget == mSnapAlgorithm.getDismissStartTarget()) {
             snapTarget = mSnapAlgorithm.getFirstSplitTarget();
         }
-        final SnapTarget finalTarget = snapTarget;
+        ValueAnimator anim = getFlingAnimator(position, snapTarget);
+        mFlingAnimationUtils.apply(anim, position, snapTarget.position, velocity);
+        anim.start();
+    }
 
+    private void flingTo(int position, SnapTarget target, long duration,
+            Interpolator interpolator) {
+        ValueAnimator anim = getFlingAnimator(position, target);
+        anim.setDuration(duration);
+        anim.setInterpolator(interpolator);
+        anim.start();
+    }
+
+    private ValueAnimator getFlingAnimator(int position, final SnapTarget snapTarget) {
         ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position);
         anim.addUpdateListener(new AnimatorUpdateListener() {
             @Override
@@ -263,19 +327,18 @@
                 resizeStack((Integer) animation.getAnimatedValue(),
                         animation.getAnimatedFraction() == 1f
                                 ? TASK_POSITION_SAME
-                                : finalTarget.position, finalTarget);
+                                : snapTarget.position, snapTarget);
             }
         });
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                commitSnapFlags(finalTarget);
+                commitSnapFlags(snapTarget);
                 mWindowManagerProxy.setResizing(false);
                 mDockSide = WindowManager.DOCKED_INVALID;
             }
         });
-        mFlingAnimationUtils.apply(anim, position, snapTarget.position, velocity);
-        anim.start();
+        return anim;
     }
 
     private void commitSnapFlags(SnapTarget target) {
@@ -348,6 +411,7 @@
         display.getDisplayInfo(info);
         mDisplayWidth = info.logicalWidth;
         mDisplayHeight = info.logicalHeight;
+        mSnapAlgorithm = null;
     }
 
     private int calculatePosition(int touchX, int touchY) {
@@ -404,6 +468,12 @@
                     restrictDismissingTaskPosition(taskPosition, mDockSide, taskSnapTarget);
             int taskPositionOther =
                     restrictDismissingTaskPosition(taskPosition, dockSideInverted, taskSnapTarget);
+
+            taskPositionDocked = minimizeHoles(position, taskPositionDocked, mDockSide,
+                    taskSnapTarget);
+            taskPositionOther = minimizeHoles(position, taskPositionOther, dockSideInverted,
+                    taskSnapTarget);
+
             calculateBoundsForPosition(taskPositionDocked, mDockSide, mDockedTaskRect);
             calculateBoundsForPosition(taskPositionOther, dockSideInverted, mOtherTaskRect);
             alignTopLeft(mDockedRect, mDockedTaskRect);
@@ -435,6 +505,51 @@
     }
 
     /**
+     * Given the current split position and the task position calculated by dragging, this
+     * method calculates a "better" task position in a sense so holes get smaller while dragging.
+     *
+     * @return the new task position
+     */
+    private int minimizeHoles(int position, int taskPosition, int dockSide,
+            SnapTarget taskSnapTarget) {
+        if (dockSideTopLeft(dockSide)) {
+            if (position > taskPosition) {
+                SnapTarget nextTarget = mSnapAlgorithm.getNextTarget(taskSnapTarget);
+
+                // If the next target is the dismiss end target, switch earlier to make the hole
+                // smaller.
+                if (nextTarget != taskSnapTarget
+                        && nextTarget == mSnapAlgorithm.getDismissEndTarget()) {
+                    float t = (float) (position - taskPosition)
+                            / (nextTarget.position - taskPosition);
+                    if (t > SWITCH_FULLSCREEN_FRACTION) {
+                        return nextTarget.position;
+                    }
+                }
+            }
+        } else if (dockSideBottomRight(dockSide)) {
+            if (position < taskPosition) {
+                SnapTarget previousTarget = mSnapAlgorithm.getPreviousTarget(taskSnapTarget);
+                if (previousTarget != taskSnapTarget) {
+                    float t = (float) (taskPosition - position)
+                            / (taskPosition - previousTarget.position);
+
+                    // In general, switch a bit earlier (at 20% instead of 50%), but if we are
+                    // dismissing the top, switch really early.
+                    float threshold = previousTarget == mSnapAlgorithm.getDismissStartTarget()
+                            ? SWITCH_FULLSCREEN_FRACTION
+                            : BOTTOM_RIGHT_SWITCH_BIGGER_FRACTION;
+                    if (t > threshold) {
+                        return previousTarget.position;
+                    }
+
+                }
+            }
+        }
+        return taskPosition;
+    }
+
+    /**
      * When the snap target is dismissing one side, make sure that the dismissing side doesn't get
      * 0 size.
      */
@@ -545,4 +660,33 @@
         inoutInfo.touchableRegion.op(mBackground.getLeft(), mBackground.getTop(),
                 mBackground.getRight(), mBackground.getBottom(), Op.UNION);
     }
+
+    public final void onBusEvent(RecentsActivityStartingEvent recentsActivityStartingEvent) {
+        if (mGrowRecents && getWindowManagerProxy().getDockSide() == WindowManager.DOCKED_TOP
+                && getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position) {
+            mGrowAfterRecentsDrawn = true;
+            startDragging(false /* animate */, false /* touching */);
+        }
+    }
+
+    public final void onBusEvent(DockingTopTaskEvent dockingEvent) {
+        if (dockingEvent.dragMode == NavigationBarGestureHelper.DRAG_MODE_NONE) {
+            mGrowAfterRecentsDrawn = false;
+            mAnimateAfterRecentsDrawn = true;
+            startDragging(false /* animate */, false /* touching */);
+        }
+    }
+
+    public final void onBusEvent(RecentsDrawnEvent drawnEvent) {
+        if (mAnimateAfterRecentsDrawn) {
+            mAnimateAfterRecentsDrawn = false;
+            stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 250,
+                    TOUCH_RESPONSE_INTERPOLATOR);
+        }
+        if (mGrowAfterRecentsDrawn) {
+            mGrowAfterRecentsDrawn = false;
+            stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 250,
+                    TOUCH_RESPONSE_INTERPOLATOR);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 38d24ce..01bfcea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
+import android.animation.TimeAnimator;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Canvas;
@@ -28,13 +29,12 @@
 import android.view.View;
 import android.view.ViewAnimationUtils;
 import android.view.ViewConfiguration;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
 import android.view.animation.PathInterpolator;
 
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingManager;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 /**
  * Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
@@ -107,11 +107,8 @@
 
     private OnActivatedListener mOnActivatedListener;
 
-    private final Interpolator mLinearOutSlowInInterpolator;
-    protected final Interpolator mFastOutSlowInInterpolator;
     private final Interpolator mSlowOutFastInInterpolator;
     private final Interpolator mSlowOutLinearInInterpolator;
-    private final Interpolator mLinearInterpolator;
     private Interpolator mCurrentAppearInterpolator;
     private Interpolator mCurrentAlphaInterpolator;
 
@@ -132,16 +129,37 @@
     private FalsingManager mFalsingManager;
     private boolean mTrackTouch;
 
+    private float mNormalBackgroundVisibilityAmount;
+    private ValueAnimator mFadeInFromDarkAnimator;
+    private ValueAnimator.AnimatorUpdateListener mBackgroundVisibilityUpdater
+            = new ValueAnimator.AnimatorUpdateListener() {
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            setNormalBackgroundVisibilityAmount(mBackgroundNormal.getAlpha());
+        }
+    };
+    private AnimatorListenerAdapter mFadeInEndListener = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            super.onAnimationEnd(animation);
+            mFadeInFromDarkAnimator = null;
+            updateOutlineAlpha();
+        }
+    };
+    private ValueAnimator.AnimatorUpdateListener mUpdateOutlineListener
+            = new ValueAnimator.AnimatorUpdateListener() {
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            updateOutlineAlpha();
+        }
+    };
+    private float mShadowAlpha = 1.0f;
+
     public ActivatableNotificationView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-        mFastOutSlowInInterpolator =
-                AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in);
         mSlowOutFastInInterpolator = new PathInterpolator(0.8f, 0.0f, 0.6f, 1.0f);
-        mLinearOutSlowInInterpolator =
-                AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
         mSlowOutLinearInInterpolator = new PathInterpolator(0.8f, 0.0f, 1.0f, 1.0f);
-        mLinearInterpolator = new LinearInterpolator();
         setClipChildren(false);
         setClipToPadding(false);
         mLegacyColor = context.getColor(R.color.notification_legacy_background_color);
@@ -166,6 +184,7 @@
         mBackgroundDimmed.setCustomBackground(R.drawable.notification_material_bg_dim);
         updateBackground();
         updateBackgroundTint();
+        updateOutlineAlpha();
     }
 
     private final Runnable mTapTimeoutRunnable = new Runnable() {
@@ -272,7 +291,7 @@
         }
     }
 
-    private void startActivateAnimation(boolean reverse) {
+    private void startActivateAnimation(final boolean reverse) {
         if (!isAttachedToWindow()) {
             return;
         }
@@ -291,8 +310,8 @@
         Interpolator interpolator;
         Interpolator alphaInterpolator;
         if (!reverse) {
-            interpolator = mLinearOutSlowInInterpolator;
-            alphaInterpolator = mLinearOutSlowInInterpolator;
+            interpolator = Interpolators.LINEAR_OUT_SLOW_IN;
+            alphaInterpolator = Interpolators.LINEAR_OUT_SLOW_IN;
         } else {
             interpolator = ACTIVATE_INVERSE_INTERPOLATOR;
             alphaInterpolator = ACTIVATE_INVERSE_ALPHA_INTERPOLATOR;
@@ -317,6 +336,16 @@
         mBackgroundNormal.animate()
                 .alpha(reverse ? 0f : 1f)
                 .setInterpolator(alphaInterpolator)
+                .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                    @Override
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        float animatedFraction = animation.getAnimatedFraction();
+                        if (reverse) {
+                            animatedFraction = 1.0f - animatedFraction;
+                        }
+                        setNormalBackgroundVisibilityAmount(animatedFraction);
+                    }
+                })
                 .setDuration(ACTIVATE_ANIMATION_LENGTH);
     }
 
@@ -377,8 +406,27 @@
         } else {
             updateBackground();
         }
-        setOutlineAlpha(dark ? 0f : 1f);
-     }
+        updateOutlineAlpha();
+    }
+
+    private void updateOutlineAlpha() {
+        if (mDark) {
+            setOutlineAlpha(0f);
+            return;
+        }
+        float alpha = NotificationStackScrollLayout.BACKGROUND_ALPHA_DIMMED;
+        alpha = (alpha + (1.0f - alpha) * mNormalBackgroundVisibilityAmount);
+        alpha *= mShadowAlpha;
+        if (mFadeInFromDarkAnimator != null) {
+            alpha *= mFadeInFromDarkAnimator.getAnimatedFraction();
+        }
+        setOutlineAlpha(alpha);
+    }
+
+    public void setNormalBackgroundVisibilityAmount(float normalBackgroundVisibilityAmount) {
+        mNormalBackgroundVisibilityAmount = normalBackgroundVisibilityAmount;
+        updateOutlineAlpha();
+    }
 
     public void setShowingLegacyBackground(boolean showing) {
         mShowingLegacyBackground = showing;
@@ -431,7 +479,7 @@
                 .scaleY(1f)
                 .setDuration(DARK_ANIMATION_LENGTH)
                 .setStartDelay(delay)
-                .setInterpolator(mLinearOutSlowInInterpolator)
+                .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
                 .setListener(new AnimatorListenerAdapter() {
                     @Override
                     public void onAnimationCancel(Animator animation) {
@@ -441,7 +489,15 @@
                         background.setAlpha(1f);
                     }
                 })
+                .setUpdateListener(mBackgroundVisibilityUpdater)
                 .start();
+        mFadeInFromDarkAnimator = TimeAnimator.ofFloat(0.0f, 1.0f);
+        mFadeInFromDarkAnimator.setDuration(DARK_ANIMATION_LENGTH);
+        mFadeInFromDarkAnimator.setStartDelay(delay);
+        mFadeInFromDarkAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+        mFadeInFromDarkAnimator.addListener(mFadeInEndListener);
+        mFadeInFromDarkAnimator.addUpdateListener(mUpdateOutlineListener);
+        mFadeInFromDarkAnimator.start();
     }
 
     /**
@@ -474,7 +530,7 @@
         mBackgroundNormal.setAlpha(startAlpha);
         mBackgroundAnimator =
                 ObjectAnimator.ofFloat(mBackgroundNormal, View.ALPHA, startAlpha, endAlpha);
-        mBackgroundAnimator.setInterpolator(mFastOutSlowInInterpolator);
+        mBackgroundAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         mBackgroundAnimator.setDuration(duration);
         mBackgroundAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
@@ -487,6 +543,7 @@
                 mBackgroundAnimator = null;
             }
         });
+        mBackgroundAnimator.addUpdateListener(mBackgroundVisibilityUpdater);
         mBackgroundAnimator.start();
     }
 
@@ -504,6 +561,8 @@
             mBackgroundNormal.setAlpha(1f);
             removeCallbacks(mTapTimeoutRunnable);
         }
+        setNormalBackgroundVisibilityAmount(
+                mBackgroundNormal.getVisibility() == View.VISIBLE ? 1.0f : 0.0f);
     }
 
     protected boolean shouldHideBackground() {
@@ -577,16 +636,16 @@
         float targetValue;
         if (isAppearing) {
             mCurrentAppearInterpolator = mSlowOutFastInInterpolator;
-            mCurrentAlphaInterpolator = mLinearOutSlowInInterpolator;
+            mCurrentAlphaInterpolator = Interpolators.LINEAR_OUT_SLOW_IN;
             targetValue = 1.0f;
         } else {
-            mCurrentAppearInterpolator = mFastOutSlowInInterpolator;
+            mCurrentAppearInterpolator = Interpolators.FAST_OUT_SLOW_IN;
             mCurrentAlphaInterpolator = mSlowOutLinearInInterpolator;
             targetValue = 0.0f;
         }
         mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction,
                 targetValue);
-        mAppearAnimator.setInterpolator(mLinearInterpolator);
+        mAppearAnimator.setInterpolator(Interpolators.LINEAR);
         mAppearAnimator.setDuration(
                 (long) (duration * Math.abs(mAppearAnimationFraction - targetValue)));
         mAppearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@@ -772,6 +831,19 @@
         return getBgColor() == otherView.getBgColor();
     }
 
+    @Override
+    public float getShadowAlpha() {
+        return mShadowAlpha;
+    }
+
+    @Override
+    public void setShadowAlpha(float shadowAlpha) {
+        if (shadowAlpha != mShadowAlpha) {
+            mShadowAlpha = shadowAlpha;
+            updateOutlineAlpha();
+        }
+    }
+
     public interface OnActivatedListener {
         void onActivated(ActivatableNotificationView view);
         void onActivationReset(ActivatableNotificationView view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 2592486..5359dd2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -81,7 +81,9 @@
 import android.widget.RemoteViews;
 import android.widget.TextView;
 import android.widget.Toast;
+
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.NotificationColorUtil;
@@ -186,7 +188,7 @@
 
     protected DevicePolicyManager mDevicePolicyManager;
     protected IDreamManager mDreamManager;
-    PowerManager mPowerManager;
+    protected PowerManager mPowerManager;
     protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
     // public mode, private notifications, etc
@@ -219,8 +221,6 @@
     // which notification is currently being longpress-examined by the user
     private NotificationGuts mNotificationGutsExposed;
 
-    private TimeInterpolator mLinearOutSlowIn, mFastOutLinearIn;
-
     private KeyboardShortcuts mKeyboardShortcuts;
 
     /**
@@ -638,11 +638,6 @@
 
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
 
-        mLinearOutSlowIn = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.linear_out_slow_in);
-        mFastOutLinearIn = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.fast_out_linear_in);
-
         // Connect in to the status bar manager service
         mCommandQueue = new CommandQueue(this);
 
@@ -954,7 +949,7 @@
             final int appUidF = appUid;
             settingsButton.setOnClickListener(new View.OnClickListener() {
                 public void onClick(View v) {
-                    MetricsLogger.action(mContext, MetricsLogger.ACTION_NOTE_INFO);
+                    MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTE_INFO);
                     startAppNotificationSettingsActivity(pkg, appUidF);
                 }
             });
@@ -1001,7 +996,7 @@
                     return false;
                 }
 
-                MetricsLogger.action(mContext, MetricsLogger.ACTION_NOTE_CONTROLS);
+                MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTE_CONTROLS);
 
                 // ensure that it's layouted but not visible until actually laid out
                 guts.setVisibility(View.INVISIBLE);
@@ -1016,7 +1011,7 @@
                         final Animator a
                                 = ViewAnimationUtils.createCircularReveal(guts, x, y, 0, r);
                         a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
-                        a.setInterpolator(mLinearOutSlowIn);
+                        a.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
                         a.start();
                         guts.setExposed(true);
                         mStackScroller.onHeightChanged(null, true /* needsAnimation */);
@@ -1048,7 +1043,7 @@
             final Animator a = ViewAnimationUtils.createCircularReveal(v,
                     x, y, r, 0);
             a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
-            a.setInterpolator(mFastOutLinearIn);
+            a.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
             a.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
index f71f092..24cd948 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
@@ -31,7 +31,7 @@
         view.animate()
                 .alpha(0f)
                 .setDuration(ANIMATION_DURATION_LENGTH)
-                .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                .setInterpolator(Interpolators.ALPHA_OUT)
                 .withEndAction(new Runnable() {
                     @Override
                     public void run() {
@@ -56,7 +56,7 @@
         view.animate()
                 .alpha(1f)
                 .setDuration(ANIMATION_DURATION_LENGTH)
-                .setInterpolator(PhoneStatusBar.ALPHA_IN)
+                .setInterpolator(Interpolators.ALPHA_IN)
                 .withEndAction(null);
         if (view.hasOverlappingRendering()) {
             view.animate().withLayer();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 8570198..5c83f5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -24,8 +24,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
+
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
@@ -53,7 +52,6 @@
     private final int[] mTemp2 = new int[2];
     private boolean mDraggedFarEnough;
     private ExpandableView mStartingChild;
-    private Interpolator mInterpolator;
     private float mLastHeight;
     private FalsingManager mFalsingManager;
 
@@ -61,8 +59,6 @@
             DragDownCallback dragDownCallback) {
         mMinDragDistance = context.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_drag_down_min_distance);
-        mInterpolator =
-                AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         mCallback = callback;
         mDragDownCallback = dragDownCallback;
@@ -187,7 +183,7 @@
         }
         ObjectAnimator anim = ObjectAnimator.ofInt(child, "actualHeight",
                 child.getActualHeight(), child.getMinHeight());
-        anim.setInterpolator(mInterpolator);
+        anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS);
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
@@ -200,7 +196,7 @@
 
     private void cancelExpansion() {
         ValueAnimator anim = ValueAnimator.ofFloat(mLastHeight, 0);
-        anim.setInterpolator(mInterpolator);
+        anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS);
         anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
             @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 52e6a9c..6fae3ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -652,8 +652,8 @@
 
     @Override
     public void setClipToActualHeight(boolean clipToActualHeight) {
-        super.setClipToActualHeight(clipToActualHeight);
-        getShowingLayout().setClipToActualHeight(clipToActualHeight);
+        super.setClipToActualHeight(clipToActualHeight || isUserLocked());
+        getShowingLayout().setClipToActualHeight(clipToActualHeight || isUserLocked());
     }
 
     /**
@@ -1126,6 +1126,11 @@
     }
 
     @Override
+    public boolean needsIncreasedPadding() {
+        return mIsSummaryWithChildren && isGroupExpanded();
+    }
+
+    @Override
     protected boolean disallowSingleClick(MotionEvent event) {
         float x = event.getX();
         float y = event.getY();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index a6fc4bb..44c6a5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -24,22 +24,17 @@
 import android.view.View;
 import android.view.ViewOutlineProvider;
 
-import com.android.systemui.R;
-
 /**
  * Like {@link ExpandableView}, but setting an outline for the height and clipping.
  */
 public abstract class ExpandableOutlineView extends ExpandableView {
 
     private final Rect mOutlineRect = new Rect();
-    protected final int mRoundedRectCornerRadius;
     private boolean mCustomOutline;
-    private float mOutlineAlpha = 1f;
+    private float mOutlineAlpha = -1f;
 
     public ExpandableOutlineView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mRoundedRectCornerRadius = getResources().getDimensionPixelSize(
-                R.dimen.notification_material_rounded_rect_radius);
         setOutlineProvider(new ViewOutlineProvider() {
             @Override
             public void getOutline(View view, Outline outline) {
@@ -49,7 +44,7 @@
                             getWidth(),
                             Math.max(getActualHeight(), mClipTopAmount));
                 } else {
-                    outline.setRoundRect(mOutlineRect, mRoundedRectCornerRadius);
+                    outline.setRect(mOutlineRect);
                 }
                 outline.setAlpha(mOutlineAlpha);
             }
@@ -69,8 +64,10 @@
     }
 
     protected void setOutlineAlpha(float alpha) {
-        mOutlineAlpha = alpha;
-        invalidateOutline();
+        if (alpha != mOutlineAlpha) {
+            mOutlineAlpha = alpha;
+            invalidateOutline();
+        }
     }
 
     protected void setOutlineRect(RectF rect) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index c190864..a0fb34a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -388,6 +388,17 @@
         return super.hasOverlappingRendering() && getActualHeight() <= getHeight();
     }
 
+    public float getShadowAlpha() {
+        return 0.0f;
+    }
+
+    public void setShadowAlpha(float shadowAlpha) {
+    }
+
+    public boolean needsIncreasedPadding() {
+        return false;
+    }
+
     /**
      * A listener notifying when {@link #getActualHeight} changes.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
index 0fa088b..c4ffd7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
@@ -19,7 +19,6 @@
 import android.animation.Animator;
 import android.content.Context;
 import android.view.ViewPropertyAnimator;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
@@ -41,8 +40,6 @@
     private static final float LINEAR_OUT_SLOW_IN_START_GRADIENT = 1.0f / LINEAR_OUT_SLOW_IN_X2;
 
     private Interpolator mLinearOutSlowIn;
-    private Interpolator mFastOutSlowIn;
-    private Interpolator mFastOutLinearIn;
 
     private float mMinVelocityPxPerSecond;
     private float mMaxLengthSeconds;
@@ -53,10 +50,6 @@
     public FlingAnimationUtils(Context ctx, float maxLengthSeconds) {
         mMaxLengthSeconds = maxLengthSeconds;
         mLinearOutSlowIn = new PathInterpolator(0, 0, LINEAR_OUT_SLOW_IN_X2, 1);
-        mFastOutSlowIn
-                = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.fast_out_slow_in);
-        mFastOutLinearIn
-                = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.fast_out_linear_in);
         mMinVelocityPxPerSecond
                 = MIN_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density;
         mHighVelocityPxPerSecond
@@ -150,7 +143,7 @@
 
             // Just use a normal interpolator which doesn't take the velocity into account.
             durationSeconds = maxLengthSeconds;
-            mAnimatorProperties.interpolator = mFastOutSlowIn;
+            mAnimatorProperties.interpolator = Interpolators.FAST_OUT_SLOW_IN;
         }
         mAnimatorProperties.duration = (long) (durationSeconds * 1000);
         return mAnimatorProperties;
@@ -223,7 +216,7 @@
 
             // Just use a normal interpolator which doesn't take the velocity into account.
             durationSeconds = maxLengthSeconds;
-            mAnimatorProperties.interpolator = mFastOutLinearIn;
+            mAnimatorProperties.interpolator = Interpolators.FAST_OUT_LINEAR_IN;
         }
         mAnimatorProperties.duration = (long) (durationSeconds * 1000);
         return mAnimatorProperties;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/Interpolators.java b/packages/SystemUI/src/com/android/systemui/statusbar/Interpolators.java
new file mode 100644
index 0000000..5979468
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/Interpolators.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.PathInterpolator;
+
+/**
+ * Utility class to receive interpolators from
+ */
+public class Interpolators {
+    public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
+    public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
+    public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
+    public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
+    public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
+    public static final Interpolator LINEAR = new LinearInterpolator();
+    public static final Interpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 8058933..841b9d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -33,13 +33,11 @@
 import android.view.RenderNodeAnimator;
 import android.view.View;
 import android.view.ViewAnimationUtils;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.ImageView;
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.KeyguardAffordanceHelper;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 /**
  * An ImageView which does not have overlapping renderings commands and therefore does not need a
@@ -55,8 +53,6 @@
 
     private final int mMinBackgroundRadius;
     private final Paint mCirclePaint;
-    private final Interpolator mAppearInterpolator;
-    private final Interpolator mDisappearInterpolator;
     private final int mInverseColor;
     private final int mNormalColor;
     private final ArgbEvaluator mColorInterpolator;
@@ -136,10 +132,6 @@
         mInverseColor = 0xff000000;
         mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_affordance_min_background_radius);
-        mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.linear_out_slow_in);
-        mDisappearInterpolator = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.fast_out_linear_in);
         mColorInterpolator = new ArgbEvaluator();
         mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.3f);
     }
@@ -261,7 +253,7 @@
             RenderNodeAnimator animator = new RenderNodeAnimator(mHwCirclePaint,
                     RenderNodeAnimator.PAINT_ALPHA, 255);
             animator.setTarget(this);
-            animator.setInterpolator(PhoneStatusBar.ALPHA_IN);
+            animator.setInterpolator(Interpolators.ALPHA_IN);
             animator.setDuration(250);
             animator.start();
         }
@@ -282,7 +274,7 @@
         RenderNodeAnimator animator = new RenderNodeAnimator(mHwCirclePaint,
                 RenderNodeAnimator.PAINT_ALPHA, 0);
         animator.setDuration(duration);
-        animator.setInterpolator(PhoneStatusBar.ALPHA_OUT);
+        animator.setInterpolator(Interpolators.ALPHA_OUT);
         animator.setTarget(this);
         animator.start();
     }
@@ -352,8 +344,8 @@
             cancelAnimator(mPreviewClipper);
             ValueAnimator animator = getAnimatorToRadius(circleRadius);
             Interpolator interpolator = circleRadius == 0.0f
-                    ? mDisappearInterpolator
-                    : mAppearInterpolator;
+                    ? Interpolators.FAST_OUT_LINEAR_IN
+                    : Interpolators.LINEAR_OUT_SLOW_IN;
             animator.setInterpolator(interpolator);
             long duration = 250;
             if (!slowAnimation) {
@@ -438,8 +430,8 @@
             animator.addListener(mScaleEndListener);
             if (interpolator == null) {
                 interpolator = imageScale == 0.0f
-                        ? mDisappearInterpolator
-                        : mAppearInterpolator;
+                        ? Interpolators.FAST_OUT_LINEAR_IN
+                        : Interpolators.LINEAR_OUT_SLOW_IN;
             }
             animator.setInterpolator(interpolator);
             if (duration == -1) {
@@ -501,8 +493,8 @@
             animator.addListener(mAlphaEndListener);
             if (interpolator == null) {
                 interpolator = alpha == 0.0f
-                        ? mDisappearInterpolator
-                        : mAppearInterpolator;
+                        ? Interpolators.FAST_OUT_LINEAR_IN
+                        : Interpolators.LINEAR_OUT_SLOW_IN;
             }
             animator.setInterpolator(interpolator);
             if (duration == -1) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 36cf906..635e66d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -52,8 +52,6 @@
     private static final int VISIBLE_TYPE_SINGLELINE = 3;
 
     private final Rect mClipBounds = new Rect();
-    private final int mRoundRectRadius;
-    private final boolean mRoundRectClippingEnabled;
     private final int mMinContractedHeight;
     private final OnLayoutChangeListener mLayoutUpdater = new OnLayoutChangeListener() {
         @Override
@@ -100,13 +98,6 @@
         }
     };
 
-    private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() {
-        @Override
-        public void getOutline(View view, Outline outline) {
-            outline.setRoundRect(0, 0, view.getWidth(), mUnrestrictedContentHeight,
-                    mRoundRectRadius);
-        }
-    };
     private OnClickListener mExpandClickListener;
     private boolean mBeforeN;
     private boolean mExpandable;
@@ -116,14 +107,9 @@
     public NotificationContentView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mHybridViewManager = new HybridNotificationViewManager(getContext(), this);
-        mRoundRectRadius = getResources().getDimensionPixelSize(
-                R.dimen.notification_material_rounded_rect_radius);
-        mRoundRectClippingEnabled = getResources().getBoolean(
-                R.bool.config_notifications_round_rect_clipping);
         mMinContractedHeight = getResources().getDimensionPixelSize(
                 R.dimen.min_notification_layout_height);
         reset(true);
-        setOutlineProvider(mOutlineProvider);
     }
 
     public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight) {
@@ -253,7 +239,6 @@
         mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child);
         selectLayout(false /* animate */, true /* force */);
         mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */);
-        updateRoundRectClipping();
     }
 
     public void setExpandedChild(View child) {
@@ -267,7 +252,6 @@
         mExpandedChild.addOnLayoutChangeListener(mLayoutUpdater);
         mExpandedWrapper = NotificationViewWrapper.wrap(getContext(), child);
         selectLayout(false /* animate */, true /* force */);
-        updateRoundRectClipping();
     }
 
     public void setHeadsUpChild(View child) {
@@ -281,7 +265,6 @@
         mHeadsUpChild.addOnLayoutChangeListener(mLayoutUpdater);
         mHeadsUpWrapper = NotificationViewWrapper.wrap(getContext(), child);
         selectLayout(false /* animate */, true /* force */);
-        updateRoundRectClipping();
     }
 
     @Override
@@ -344,27 +327,6 @@
         updateClipping();
     }
 
-    private void updateRoundRectClipping() {
-        boolean enabled = needsRoundRectClipping();
-        setClipToOutline(enabled);
-    }
-
-    private boolean needsRoundRectClipping() {
-        if (!mRoundRectClippingEnabled) {
-            return false;
-        }
-        boolean needsForContracted = mContractedChild != null
-                && mContractedChild.getVisibility() == View.VISIBLE
-                && mContractedWrapper.needsRoundRectClipping();
-        boolean needsForExpanded = mExpandedChild != null
-                && mExpandedChild.getVisibility() == View.VISIBLE
-                && mExpandedWrapper.needsRoundRectClipping();
-        boolean needsForHeadsUp = mExpandedChild != null
-                && mExpandedChild.getVisibility() == View.VISIBLE
-                && mExpandedWrapper.needsRoundRectClipping();
-        return needsForContracted || needsForExpanded || needsForHeadsUp;
-    }
-
     private void updateClipping() {
         if (mClipToActualHeight) {
             mClipBounds.set(0, mClipTopAmount, getWidth(), mContentHeight);
@@ -412,7 +374,6 @@
             boolean singleLineVisible = visibleType == VISIBLE_TYPE_SINGLELINE;
             mSingleLineView.setVisible(singleLineVisible);
         }
-        updateRoundRectClipping();
     }
 
     private void animateToVisibleType(int visibleType) {
@@ -426,7 +387,6 @@
                 hiddenView.setVisible(false);
             }
         });
-        updateRoundRectClipping();
     }
 
     /**
@@ -553,7 +513,6 @@
         if (mHeadsUpChild != null) {
             mHeadsUpWrapper.notifyContentUpdated(entry.notification);
         }
-        updateRoundRectClipping();
     }
 
     private void updateSingleLineView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index e4cd7d9..5abd1d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -206,13 +206,8 @@
     void saveImportance(final StatusBarNotification sbn) {
         int progress = mSeekBar.getProgress();
         try {
-            if (mApplyToTopic.isChecked()) {
-                mINotificationManager.setTopicImportance(sbn.getPackageName(), sbn.getUid(), mTopic,
-                        progress);
-            } else {
-                mINotificationManager.setAppImportance(
-                        sbn.getPackageName(), sbn.getUid(), progress);
-            }
+            mINotificationManager.setImportance(sbn.getPackageName(), sbn.getUid(),
+                    mApplyToTopic.isChecked() ? mTopic : null, progress);
         } catch (RemoteException e) {
             // :(
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index 682676b..4e3ecb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -22,7 +22,10 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Paint;
 import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.Interpolator;
@@ -32,11 +35,14 @@
  */
 public class ScrimView extends View
 {
+    private final Paint mPaint = new Paint();
     private int mScrimColor;
     private boolean mIsEmpty = true;
     private boolean mDrawAsSrc;
     private float mViewAlpha = 1.0f;
     private ValueAnimator mAlphaAnimator;
+    private Rect mExcludedRect = new Rect();
+    private boolean mHasExcludedArea;
     private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener
             = new ValueAnimator.AnimatorUpdateListener() {
         @Override
@@ -51,6 +57,7 @@
             mAlphaAnimator = null;
         }
     };
+    private Runnable mChangeRunnable;
 
     public ScrimView(Context context) {
         this(context, null);
@@ -72,15 +79,43 @@
     protected void onDraw(Canvas canvas) {
         if (mDrawAsSrc || (!mIsEmpty && mViewAlpha > 0f)) {
             PorterDuff.Mode mode = mDrawAsSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER;
-            int color = mScrimColor;
-            color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color),
-                    Color.green(color), Color.blue(color));
-            canvas.drawColor(color, mode);
+            int color = getScrimColorWithAlpha();
+            if (!mHasExcludedArea) {
+                canvas.drawColor(color, mode);
+            } else {
+                mPaint.setColor(color);
+                if (mExcludedRect.top > 0) {
+                    canvas.drawRect(0, 0, getWidth(), mExcludedRect.top, mPaint);
+                }
+                if (mExcludedRect.left > 0) {
+                    canvas.drawRect(0,  mExcludedRect.top, mExcludedRect.left, mExcludedRect.bottom,
+                            mPaint);
+                }
+                if (mExcludedRect.right < getWidth()) {
+                    canvas.drawRect(mExcludedRect.right,
+                            mExcludedRect.top,
+                            getWidth(),
+                            mExcludedRect.bottom,
+                            mPaint);
+                }
+                if (mExcludedRect.bottom < getHeight()) {
+                    canvas.drawRect(0,  mExcludedRect.bottom, getWidth(), getHeight(), mPaint);
+                }
+            }
         }
     }
 
+    public int getScrimColorWithAlpha() {
+        int color = mScrimColor;
+        color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color),
+                Color.green(color), Color.blue(color));
+        return color;
+    }
+
     public void setDrawAsSrc(boolean asSrc) {
         mDrawAsSrc = asSrc;
+        mPaint.setXfermode(new PorterDuffXfermode(mDrawAsSrc ? PorterDuff.Mode.SRC
+                : PorterDuff.Mode.SRC_OVER));
         invalidate();
     }
 
@@ -89,6 +124,9 @@
             mIsEmpty = Color.alpha(color) == 0;
             mScrimColor = color;
             invalidate();
+            if (mChangeRunnable != null) {
+                mChangeRunnable.run();
+            }
         }
     }
 
@@ -105,8 +143,13 @@
         if (mAlphaAnimator != null) {
             mAlphaAnimator.cancel();
         }
-        mViewAlpha = alpha;
-        invalidate();
+        if (alpha != mViewAlpha) {
+            mViewAlpha = alpha;
+            invalidate();
+            if (mChangeRunnable != null) {
+                mChangeRunnable.run();
+            }
+        }
     }
 
     public void animateViewAlpha(float alpha, long durationOut, Interpolator interpolator) {
@@ -120,4 +163,23 @@
         mAlphaAnimator.setDuration(durationOut);
         mAlphaAnimator.start();
     }
+
+    public void setExcludedArea(Rect area) {
+        if (area == null) {
+            mHasExcludedArea = false;
+            invalidate();
+            return;
+        }
+        area.left = Math.max(area.left, 0);
+        area.top = Math.max(area.top, 0);
+        area.right = Math.min(area.right, getWidth());
+        area.bottom = Math.min(area.bottom, getHeight());
+        mExcludedRect.set(area);
+        mHasExcludedArea = area.left < area.right && area.top < area.bottom;
+        invalidate();
+    }
+
+    public void setChangeRunnable(Runnable changeRunnable) {
+        mChangeRunnable = changeRunnable;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
deleted file mode 100644
index 1fc8744..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import com.android.systemui.R;
-
-/**
- * The view representing the separation between important and less important notifications
- */
-public class SpeedBumpView extends ExpandableView {
-
-    private final int mSpeedBumpHeight;
-    private AlphaOptimizedView mLine;
-    private boolean mIsVisible = true;
-    private final Interpolator mFastOutSlowInInterpolator;
-
-    public SpeedBumpView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mSpeedBumpHeight = getResources()
-                .getDimensionPixelSize(R.dimen.speed_bump_height);
-        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
-                android.R.interpolator.fast_out_slow_in);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mLine = (AlphaOptimizedView) findViewById(R.id.speedbump_line);
-    }
-
-    @Override
-    protected int getInitialHeight() {
-        return mSpeedBumpHeight;
-    }
-
-    @Override
-    public int getIntrinsicHeight() {
-        return mSpeedBumpHeight;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        mLine.setPivotX(mLine.getWidth() / 2);
-        mLine.setPivotY(mLine.getHeight() / 2);
-        setOutlineProvider(null);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        measureChildren(widthMeasureSpec, heightMeasureSpec);
-        int height = mSpeedBumpHeight;
-        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
-    }
-
-    @Override
-    public boolean isTransparent() {
-        return true;
-    }
-
-    public void performVisibilityAnimation(boolean nowVisible, long delay) {
-        animateDivider(nowVisible, delay, null /* onFinishedRunnable */);
-    }
-
-    /**
-     * Animate the divider to a new visibility.
-     *
-     * @param nowVisible should it now be visible
-     * @param delay the delay after the animation should start
-     * @param onFinishedRunnable A runnable which should be run when the animation is
-     *        finished.
-     */
-    public void animateDivider(boolean nowVisible, long delay, Runnable onFinishedRunnable) {
-        if (nowVisible != mIsVisible) {
-            // Animate dividers
-            float endValue = nowVisible ? 1.0f : 0.0f;
-            mLine.animate()
-                    .alpha(endValue)
-                    .setStartDelay(delay)
-                    .scaleX(endValue)
-                    .scaleY(endValue)
-                    .setInterpolator(mFastOutSlowInInterpolator)
-                    .withEndAction(onFinishedRunnable);
-            mIsVisible = nowVisible;
-        } else {
-            if (onFinishedRunnable != null) {
-                onFinishedRunnable.run();
-            }
-        }
-    }
-
-    public void setInvisible() {
-        mLine.setAlpha(0.0f);
-        mLine.setScaleX(0.0f);
-        mLine.setScaleY(0.0f);
-        mIsVisible = false;
-    }
-
-    @Override
-    public void performRemoveAnimation(long duration, float translationDirection,
-            Runnable onFinishedRunnable) {
-        // TODO: Use duration
-        performVisibilityAnimation(false, 0 /* delay */);
-    }
-
-    @Override
-    public void performAddAnimation(long delay, long duration) {
-        // TODO: Use duration
-        performVisibilityAnimation(true, delay);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
index 2f66c41..c836637 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
@@ -21,8 +21,6 @@
 import android.view.View;
 import android.view.animation.Interpolator;
 
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
-
 /**
  * A common base class for all views in the notification stack scroller which don't have a
  * background.
@@ -80,9 +78,9 @@
             float endValue = nowVisible ? 1.0f : 0.0f;
             Interpolator interpolator;
             if (nowVisible) {
-                interpolator = PhoneStatusBar.ALPHA_IN;
+                interpolator = Interpolators.ALPHA_IN;
             } else {
-                interpolator = PhoneStatusBar.ALPHA_OUT;
+                interpolator = Interpolators.ALPHA_OUT;
             }
             mAnimating = true;
             mContent.animate()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
index 3e2c4c6..bed64a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
@@ -39,6 +39,10 @@
  * the navigation buttons by updating arrays_car.xml appropriately in an overlay.
  */
 class CarNavigationBarController {
+    private static final String EXTRA_FACET_CATEGORIES = "categories";
+    private static final String EXTRA_FACET_PACKAGES = "packages";
+    private static final String EXTRA_FACET_ID = "filter_id";
+    private static final String EXTRA_FACET_LAUNCH_PICKER = "launch_picker";
 
     // Each facet of the navigation bar maps to a set of package names or categories defined in
     // arrays_car.xml. Package names for a given facet are delimited by ";"
@@ -64,6 +68,7 @@
     private List<CarNavigationButton> mNavButtons = new ArrayList<CarNavigationButton>();
 
     private int mCurrentFacetIndex;
+    private String mCurrentPackageName;
 
     public CarNavigationBarController(Context context,
                                       CarNavigationBarView navBar,
@@ -75,6 +80,7 @@
     }
 
     public void taskChanged(String packageName) {
+        mCurrentPackageName = packageName;
         // If the package name belongs to a filter, then highlight appropriate button in
         // the navigation bar.
         if (mFacetPackageMap.containsKey(packageName)) {
@@ -121,7 +127,8 @@
 
                 CarNavigationButton button = createNavButton(icon, i, hasLongpress);
                 mNavButtons.add(button);
-                mNavBar.addButton(button, createNavButton(icon, i, hasLongpress));
+                mNavBar.addButton(button,
+                        createNavButton(icon, i, hasLongpress) /* lightsOutButton */);
 
                 initFacetFilterMaps(i,
                         facetPackageNames.getString(i).split(FACET_FILTER_DEMILITER),
@@ -132,7 +139,7 @@
         }
     }
 
-    private void initFacetFilterMaps(int id, String[] packageNames, String[] categories){
+    private void initFacetFilterMaps(int id, String[] packageNames, String[] categories) {
         mFacetCategories.add(categories);
         for (int i = 0; i < categories.length; i++) {
             mFacetCategoryMap.put(categories[i], id);
@@ -234,7 +241,6 @@
         button.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                setCurrentFacet(id);
                 onFacetClicked(id);
             }
         });
@@ -245,13 +251,13 @@
                 @Override
                 public boolean onLongClick(View v) {
                     onFacetLongClicked(id);
-                    setCurrentFacet(id);
                     return true;
                 }
             });
         } else {
             button.setLongClickable(false);
         }
+
         return button;
     }
 
@@ -262,14 +268,35 @@
     }
 
     private void onFacetClicked(int index) {
-        // TODO: determine what data to pass to the trampoline, so it can start
-        // the default app or the lens picker.
-        startActivity(mIntents.get(index));
+        Intent intent = mIntents.get(index);
+        String packageName = intent.getPackage();
+
+        if (packageName == null) {
+            return;
+        }
+
+        // Don't launch the lens picker if it's already running and the
+        // user clicks the same facet
+        if (packageName.equals(mCurrentPackageName) && index == mCurrentFacetIndex) {
+            return;
+        }
+
+        intent.putExtra(EXTRA_FACET_CATEGORIES, mFacetCategories.get(index));
+        intent.putExtra(EXTRA_FACET_PACKAGES, mFacetPackages.get(index));
+        // The facet is identified by the index in which it was added to the nav bar.
+        // This value can be used to determine which facet was selected
+        intent.putExtra(EXTRA_FACET_ID, Integer.toString(index));
+
+        // If the current facet is clicked, we want to launch the picker by default
+        // rather than the "preferred/last run" app.
+        intent.putExtra(EXTRA_FACET_LAUNCH_PICKER, index == mCurrentFacetIndex);
+
+        setCurrentFacet(index);
+        startActivity(intent);
     }
 
     private void onFacetLongClicked(int index) {
-        // TODO: determine what data to pass to the trampoline, so it can start
-        // the default app or the lens picker.
+        setCurrentFacet(index);
         startActivity(mLongPressIntents.get(index));
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index 36b3a8a..504f059 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -18,8 +18,6 @@
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.widget.ImageButton;
-import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import com.android.keyguard.AlphaOptimizedImageButton;
 import com.android.systemui.R;
@@ -43,13 +41,11 @@
         super.onFinishInflate();
         mIcon = (AlphaOptimizedImageButton) findViewById(R.id.car_nav_button_icon);
         mIcon.setClickable(false);
-        mIcon.setScaleType(ImageView.ScaleType.CENTER);
         mIcon.setBackgroundColor(android.R.color.transparent);
         mIcon.setAlpha(UNSELECTED_ALPHA);
 
         mMoreIcon = (AlphaOptimizedImageButton) findViewById(R.id.car_nav_button_more_icon);
         mMoreIcon.setClickable(false);
-        mMoreIcon.setScaleType(ImageView.ScaleType.CENTER);
         mMoreIcon.setBackgroundColor(android.R.color.transparent);
         mMoreIcon.setVisibility(INVISIBLE);
         mMoreIcon.setImageDrawable(getContext().getDrawable(R.drawable.car_ic_arrow));
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 f6f1f94..e20936b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -24,11 +24,13 @@
 import android.os.Looper;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
+import android.view.ViewStub;
 import android.view.WindowManager;
 
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 /**
@@ -41,6 +43,7 @@
 
     private CarNavigationBarView mCarNavigationBar;
     private CarNavigationBarController mController;
+    private FullscreenUserSwitcher mFullscreenUserSwitcher;
 
     @Override
     public void start() {
@@ -102,6 +105,10 @@
         }
 
         @Override
+        public void onPinnedActivityRestartAttempt() {
+        }
+
+        @Override
         public void onTaskStackChanged() {
             mHandler.removeCallbacks(this);
             mHandler.post(this);
@@ -121,4 +128,34 @@
             }
         }
     }
+
+    @Override
+    protected void createUserSwitcher() {
+        if (mUserSwitcherController.useFullscreenUserSwitcher()) {
+            mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, mUserSwitcherController,
+                    (ViewStub) mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub));
+        } else {
+            super.createUserSwitcher();
+        }
+    }
+
+    @Override
+    public void userSwitched(int newUserId) {
+        super.userSwitched(newUserId);
+        if (mFullscreenUserSwitcher != null) {
+            mFullscreenUserSwitcher.onUserSwitched(newUserId);
+        }
+    }
+
+    @Override
+    public void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
+        super.updateKeyguardState(goingToFullShade, fromShadeLocked);
+        if (mFullscreenUserSwitcher != null) {
+            if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
+                mFullscreenUserSwitcher.show();
+            } else {
+                mFullscreenUserSwitcher.hide();
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/FullscreenUserSwitcher.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index fd8852e..3025092 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.statusbar.car;
 
 import android.content.Context;
 import android.provider.Settings;
@@ -22,8 +22,8 @@
 import android.view.ViewStub;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.UserGridView;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
 
 /**
  * Manages the fullscreen user switcher.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
index 2f8bc2d..28f4e05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.systemui.statusbar;
+package com.android.systemui.statusbar.car;
 
 import android.content.Context;
 import android.content.DialogInterface;
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 fd65aac..97bf4b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -41,9 +41,4 @@
             mInvertHelper.update(dark);
         }
     }
-
-    @Override
-    public boolean needsRoundRectClipping() {
-        return true;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 4fd4cab..f43a5d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -38,6 +38,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
@@ -55,7 +56,6 @@
             0, PorterDuff.Mode.SRC_ATOP);
     private final int mIconDarkAlpha;
     private final int mIconDarkColor = 0xffffffff;
-    protected final Interpolator mLinearOutSlowInInterpolator;
     protected final ViewInvertHelper mInvertHelper;
 
     protected final ViewTransformationHelper mTransformationHelper;
@@ -69,8 +69,6 @@
     protected NotificationHeaderViewWrapper(Context ctx, View view) {
         super(view);
         mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
-        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx,
-                android.R.interpolator.linear_out_slow_in);
         mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
         resolveHeaderViews();
@@ -185,7 +183,7 @@
         ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
         animator.addUpdateListener(updateListener);
         animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
-        animator.setInterpolator(mLinearOutSlowInInterpolator);
+        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
         animator.setStartDelay(delay);
         if (listener != null) {
             animator.addListener(listener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index a959e07..3475d13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -26,6 +26,7 @@
 import android.widget.TextView;
 
 import com.android.systemui.statusbar.CrossFadeHelper;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -64,7 +65,7 @@
                                             - ownPosition[1]) * 0.33f)
                                     .setDuration(
                                             StackStateAnimator.ANIMATION_DURATION_STANDARD)
-                                    .setInterpolator(TransformState.FAST_OUT_SLOW_IN)
+                                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                                     .withEndAction(new Runnable() {
                                         @Override
                                         public void run() {
@@ -103,7 +104,7 @@
                                     .translationY(0)
                                     .setDuration(
                                             StackStateAnimator.ANIMATION_DURATION_STANDARD)
-                                    .setInterpolator(TransformState.FAST_OUT_SLOW_IN)
+                                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                                     .withEndAction(new Runnable() {
                                         @Override
                                         public void run() {
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 0ceba78..a1cf07e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -65,14 +65,6 @@
     public void notifyContentUpdated(StatusBarNotification notification) {};
 
     /**
-     * @return true if this template might need to be clipped with a round rect to make it look
-     *         nice, false otherwise
-     */
-    public boolean needsRoundRectClipping() {
-        return false;
-    }
-
-    /**
      * Update the appearance of the expand button.
      *
      * @param expandable should this view be expandable
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 388ba0e..3e1c40a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -22,8 +22,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
 import android.widget.ImageView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
@@ -31,6 +29,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 
 /**
@@ -44,7 +43,6 @@
     private static final int CLIP_CLIPPING_SET = R.id.clip_children_set_tag;
     private static final int CLIP_CHILDREN_TAG = R.id.clip_children_tag;
     private static final int CLIP_TO_PADDING = R.id.clip_to_padding_tag;
-    public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
     private static Pools.SimplePool<TransformState> sInstancePool = new Pools.SimplePool<>(40);
 
     protected View mTransformedView;
@@ -110,7 +108,7 @@
             }
         }
         transformedView.animate()
-                .setInterpolator(TransformState.FAST_OUT_SLOW_IN)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
                 .withEndAction(new Runnable() {
                     @Override
@@ -168,7 +166,7 @@
                     .translationY(otherStablePosition[1] - ownPosition[1]);
         }
         transformedView.animate()
-                .setInterpolator(TransformState.FAST_OUT_SLOW_IN)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
                 .withEndAction(new Runnable() {
                     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index a3f404a..37e5558 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -32,6 +32,7 @@
 import android.view.animation.LinearInterpolator;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.Interpolators;
 
 public class BarTransitions {
     private static final boolean DEBUG = false;
@@ -124,7 +125,6 @@
         private final int mTransparent;
         private final int mWarning;
         private final Drawable mGradient;
-        private final TimeInterpolator mInterpolator;
 
         private int mMode = -1;
         private boolean mAnimating;
@@ -152,7 +152,6 @@
                 mWarning = context.getColor(com.android.internal.R.color.battery_saver_mode_color);
             }
             mGradient = context.getDrawable(gradientResourceId);
-            mInterpolator = new LinearInterpolator();
         }
 
         @Override
@@ -222,7 +221,8 @@
                     mGradientAlpha = targetGradientAlpha;
                 } else {
                     final float t = (now - mStartTime) / (float)(mEndTime - mStartTime);
-                    final float v = Math.max(0, Math.min(mInterpolator.getInterpolation(t), 1));
+                    final float v = Math.max(0, Math.min(
+                            Interpolators.LINEAR.getInterpolation(t), 1));
                     mGradientAlpha = (int)(v * targetGradientAlpha + mGradientAlphaStart * (1 - v));
                     mColor = Color.argb(
                           (int)(v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1 - v)),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
index 8e3886b..aea9e1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
@@ -76,11 +76,11 @@
     }
 
     public int getVisibility() {
-        return mVisibility;
+        return mVisibility != null ? mVisibility : View.VISIBLE;
     }
 
     public float getAlpha() {
-        return mAlpha;
+        return mAlpha != null ? mAlpha : 1;
     }
 
     public void setImageDrawable(Drawable drawable) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 3ff69c9..b5dba18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -23,11 +23,11 @@
 import android.content.Context;
 import android.os.Handler;
 import android.util.Log;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
+import com.android.systemui.statusbar.Interpolators;
 
 /**
  * Controller which handles all the doze animations of the scrims.
@@ -37,10 +37,6 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final DozeParameters mDozeParameters;
-    private final Interpolator mPulseInInterpolator = PhoneStatusBar.ALPHA_OUT;
-    private final Interpolator mPulseInInterpolatorPickup;
-    private final Interpolator mPulseOutInterpolator = PhoneStatusBar.ALPHA_IN;
-    private final Interpolator mDozeAnimationInterpolator;
     private final Handler mHandler = new Handler();
     private final ScrimController mScrimController;
 
@@ -55,8 +51,6 @@
     public DozeScrimController(ScrimController scrimController, Context context) {
         mScrimController = scrimController;
         mDozeParameters = new DozeParameters(context);
-        mDozeAnimationInterpolator = mPulseInInterpolatorPickup =
-                AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
     }
 
     public void setDozing(boolean dozing, boolean animate) {
@@ -70,9 +64,11 @@
             cancelPulsing();
             if (animate) {
                 startScrimAnimation(false /* inFront */, 0f /* target */,
-                        NotificationPanelView.DOZE_ANIMATION_DURATION, mDozeAnimationInterpolator);
+                        NotificationPanelView.DOZE_ANIMATION_DURATION,
+                        Interpolators.LINEAR_OUT_SLOW_IN);
                 startScrimAnimation(true /* inFront */, 0f /* target */,
-                        NotificationPanelView.DOZE_ANIMATION_DURATION, mDozeAnimationInterpolator);
+                        NotificationPanelView.DOZE_ANIMATION_DURATION,
+                        Interpolators.LINEAR_OUT_SLOW_IN);
             } else {
                 abortAnimations();
                 mScrimController.setDozeBehindAlpha(0f);
@@ -116,7 +112,7 @@
             final boolean pickup = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
             startScrimAnimation(true /* inFront */, 0f,
                     mDozeParameters.getPulseInDuration(pickup),
-                    pickup ? mPulseInInterpolatorPickup : mPulseInInterpolator,
+                    pickup ? Interpolators.LINEAR_OUT_SLOW_IN : Interpolators.ALPHA_OUT,
                     mPulseInFinished);
         }
     }
@@ -266,7 +262,7 @@
             if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
             if (!mDozing) return;
             startScrimAnimation(true /* inFront */, 1f, mDozeParameters.getPulseOutDuration(),
-                    mPulseOutInterpolator, mPulseOutFinished);
+                    Interpolators.ALPHA_IN, mPulseOutFinished);
         }
     };
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java
deleted file mode 100644
index d2bec7c..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/GetActivityIconTask.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import android.app.AppGlobals;
-import android.content.pm.ActivityInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Typeface;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
-import android.os.RemoteException;
-import android.util.Slog;
-import android.widget.ImageView;
-
-/**
- * Retrieves the icon for an activity and sets it as the Drawable on an ImageView. The ImageView
- * is hidden if the activity isn't recognized or if there is no icon.
- */
-class GetActivityIconTask extends AsyncTask<AppButtonData, Void, Drawable> {
-    private final static String TAG = "GetActivityIconTask";
-
-    private final PackageManager mPackageManager;
-
-    // The ImageView that will receive the icon.
-    private final ImageView mImageView;
-
-    public GetActivityIconTask(PackageManager packageManager, ImageView imageView) {
-        mPackageManager = packageManager;
-        mImageView = imageView;
-    }
-
-    @Override
-    protected Drawable doInBackground(AppButtonData... params) {
-        if (params.length != 1) {
-            throw new IllegalArgumentException("Expected one parameter");
-        }
-        AppButtonData buttonData = params[0];
-        AppInfo appInfo = buttonData.appInfo;
-        try {
-            IPackageManager mPM = AppGlobals.getPackageManager();
-            ActivityInfo ai = mPM.getActivityInfo(
-                    appInfo.getComponentName(),
-                    0,
-                    appInfo.getUser().getIdentifier());
-
-            if (ai == null) {
-                Slog.w(TAG, "Icon not found for " + appInfo);
-                return null;
-            }
-
-            Drawable unbadgedIcon = ai.loadIcon(mPackageManager);
-            Drawable badgedIcon =
-                    mPackageManager.getUserBadgedIcon(unbadgedIcon, appInfo.getUser());
-
-            if (NavigationBarApps.DEBUG) {
-                // Draw pinned indicator and number of running tasks.
-                Bitmap bitmap = Bitmap.createBitmap(
-                        badgedIcon.getIntrinsicWidth(),
-                        badgedIcon.getIntrinsicHeight(),
-                        Bitmap.Config.ARGB_8888);
-                Canvas canvas = new Canvas(bitmap);
-                badgedIcon.setBounds(
-                        0, 0, badgedIcon.getIntrinsicWidth(), badgedIcon.getIntrinsicHeight());
-                badgedIcon.draw(canvas);
-                Paint paint = new Paint();
-                paint.setStyle(Paint.Style.FILL);
-                if (buttonData.pinned) {
-                    paint.setColor(Color.WHITE);
-                    canvas.drawCircle(10, 10, 10, paint);
-                }
-                if (buttonData.tasks != null && buttonData.tasks.size() > 0) {
-                    paint.setColor(Color.BLACK);
-                    canvas.drawCircle(60, 30, 30, paint);
-                    paint.setColor(Color.WHITE);
-                    paint.setTextSize(50);
-                    paint.setTypeface(Typeface.create("sans-serif", Typeface.BOLD));
-                    canvas.drawText(Integer.toString(buttonData.tasks.size()), 50, 50, paint);
-                }
-                badgedIcon = new BitmapDrawable(null, bitmap);
-            }
-
-            return  badgedIcon;
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Icon not found for " + appInfo, e);
-            return null;
-        }
-    }
-
-    @Override
-    protected void onPostExecute(Drawable icon) {
-        mImageView.setImageDrawable(icon);
-    }
-}
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 26abc48..e7064e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -43,7 +43,6 @@
     private boolean mCollapseSnoozes;
     private NotificationPanelView mPanel;
     private ExpandableNotificationRow mPickedChild;
-    private final int mNotificationsTopPadding;
 
     public HeadsUpTouchHelper(HeadsUpManager headsUpManager,
             NotificationStackScrollLayout stackScroller,
@@ -54,8 +53,6 @@
         Context context = stackScroller.getContext();
         final ViewConfiguration configuration = ViewConfiguration.get(context);
         mTouchSlop = configuration.getScaledTouchSlop();
-        mNotificationsTopPadding = context.getResources()
-                .getDimensionPixelSize(R.dimen.notifications_top_padding);
     }
 
     public boolean isTrackingHeadsUp() {
@@ -80,10 +77,6 @@
                 mInitialTouchX = x;
                 setTrackingHeadsUp(false);
                 ExpandableView child = mStackScroller.getChildAtRawPosition(x, y);
-                if (child == null && y < mNotificationsTopPadding) {
-                    // We should also allow drags from the margin above the heads up
-                    child = mStackScroller.getChildAtRawPosition(x, y + mNotificationsTopPadding);
-                }
                 mTouchingHeadsUpView = false;
                 if (child instanceof ExpandableNotificationRow) {
                     mPickedChild = (ExpandableNotificationRow) child;
@@ -113,8 +106,7 @@
                     mHeadsUpManager.unpinAll();
                     mPanel.setPanelScrimMinFraction((float) expandedHeight
                             / mPanel.getMaxPanelHeight());
-                    mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight
-                            + mNotificationsTopPadding);
+                    mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight);
                     mPanel.clearNotificattonEffects();
                     return true;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 41adeb5..c220efe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -24,12 +24,11 @@
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
 
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 
 /**
@@ -60,8 +59,6 @@
     private KeyguardAffordanceView mLeftIcon;
     private KeyguardAffordanceView mCenterIcon;
     private KeyguardAffordanceView mRightIcon;
-    private Interpolator mAppearInterpolator;
-    private Interpolator mDisappearInterpolator;
     private Animator mSwipeAnimator;
     private FalsingManager mFalsingManager;
     private int mMinBackgroundRadius;
@@ -107,10 +104,6 @@
         mHintGrowAmount =
                 mContext.getResources().getDimensionPixelSize(R.dimen.hint_grow_amount_sideways);
         mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.4f);
-        mAppearInterpolator = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.linear_out_slow_in);
-        mDisappearInterpolator = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.fast_out_linear_in);
         mFalsingManager = FalsingManager.getInstance(mContext);
     }
 
@@ -272,7 +265,7 @@
                 }
             }
         });
-        animator.setInterpolator(mAppearInterpolator);
+        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
         animator.setDuration(HINT_PHASE1_DURATION);
         animator.start();
         mSwipeAnimator = animator;
@@ -292,7 +285,7 @@
                 onFinishedListener.run();
             }
         });
-        animator.setInterpolator(mDisappearInterpolator);
+        animator.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
         animator.setDuration(HINT_PHASE2_DURATION);
         animator.setStartDelay(HINT_CIRCLE_OPEN_DURATION);
         animator.start();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 14176a6..94d3829 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -58,6 +58,7 @@
 import com.android.systemui.R;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.policy.AccessibilityController;
@@ -111,7 +112,6 @@
     private AccessibilityController mAccessibilityController;
     private PhoneStatusBar mPhoneStatusBar;
 
-    private final Interpolator mLinearOutSlowInInterpolator;
     private boolean mUserSetupComplete;
     private boolean mPrewarmBound;
     private Messenger mPrewarmMessenger;
@@ -146,8 +146,6 @@
     public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mLinearOutSlowInInterpolator =
-                AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
     }
 
     private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
@@ -600,7 +598,7 @@
         mIndicationText.setAlpha(0f);
         mIndicationText.animate()
                 .alpha(1f)
-                .setInterpolator(mLinearOutSlowInInterpolator)
+                .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
                 .setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
     }
 
@@ -610,7 +608,7 @@
         element.animate()
                 .alpha(1f)
                 .translationY(0f)
-                .setInterpolator(mLinearOutSlowInInterpolator)
+                .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
                 .setStartDelay(delay)
                 .setDuration(DOZE_ANIMATION_ELEMENT_DURATION);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index f41e47b..e67aa84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -23,14 +23,13 @@
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewTreeObserver;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.policy.UserInfoController;
@@ -58,7 +57,6 @@
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
 
     private int mSystemIconsSwitcherHiddenExpandedMargin;
-    private Interpolator mFastOutSlowInInterpolator;
 
     public KeyguardStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -73,8 +71,6 @@
         mBatteryLevel = (TextView) findViewById(R.id.battery_level);
         mCarrierLabel = (TextView) findViewById(R.id.keyguard_carrier_text);
         loadDimens();
-        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
-                android.R.interpolator.fast_out_slow_in);
         updateUserSwitcher();
     }
 
@@ -199,7 +195,7 @@
                         .translationX(0)
                         .setDuration(400)
                         .setStartDelay(userSwitcherHiding ? 300 : 0)
-                        .setInterpolator(mFastOutSlowInInterpolator)
+                        .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                         .start();
                 if (userSwitcherHiding) {
                     getOverlay().add(mMultiUserSwitch);
@@ -207,7 +203,7 @@
                             .alpha(0f)
                             .setDuration(300)
                             .setStartDelay(0)
-                            .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                            .setInterpolator(Interpolators.ALPHA_OUT)
                             .withEndAction(new Runnable() {
                                 @Override
                                 public void run() {
@@ -223,7 +219,7 @@
                             .alpha(1f)
                             .setDuration(300)
                             .setStartDelay(200)
-                            .setInterpolator(PhoneStatusBar.ALPHA_IN);
+                            .setInterpolator(Interpolators.ALPHA_IN);
                 }
                 return true;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 71267cd..8717a15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -65,6 +65,10 @@
         setUserSwitcherController(qsPanel.getHost().getUserSwitcherController());
     }
 
+    public boolean hasMultipleUsers() {
+        return mUserListener.getCount() != 0;
+    }
+
     public void setUserSwitcherController(UserSwitcherController userSwitcherController) {
         mUserSwitcherController = userSwitcherController;
         registerListener();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
deleted file mode 100644
index d0c14f1..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-
-import android.animation.LayoutTransition;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.app.ActivityManager.RecentTaskInfo;
-import android.app.ActivityManagerNative;
-import android.app.ActivityOptions;
-import android.app.IActivityManager;
-import android.app.ITaskStackListener;
-import android.content.BroadcastReceiver;
-import android.content.ClipData;
-import android.content.ClipDescription;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.DragEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.PopupMenu;
-import android.widget.Toast;
-
-import com.android.internal.content.PackageMonitor;
-import com.android.systemui.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Container for application icons that appear in the navigation bar. Their appearance is similar
- * to the launcher hotseat. Clicking an icon launches or activates the associated activity. A long
- * click will trigger a drag to allow the icons to be reordered. As an icon is dragged the other
- * icons shift to make space for it to be dropped. These layout changes are animated.
- * Navigation bar contains both pinned and unpinned apps: pinned in the left part, unpinned in the
- * right part, with no separator in between.
- */
-class NavigationBarApps extends LinearLayout
-        implements NavigationBarAppsModel.OnAppsChangedListener {
-    public final static boolean DEBUG = false;
-    private final static String TAG = "NavigationBarApps";
-
-    /**
-     * Intent extra to store user serial number.
-     */
-    static final String EXTRA_PROFILE = "profile";
-
-    // There are separate NavigationBarApps view instances for landscape vs. portrait, but they
-    // share the data model.
-    private static NavigationBarAppsModel sAppsModel;
-
-    private final PackageManager mPackageManager;
-    private final UserManager mUserManager;
-    private final LayoutInflater mLayoutInflater;
-    private final AppPackageMonitor mAppPackageMonitor;
-    private final WindowManager mWindowManager;
-
-
-    // This view has two roles:
-    // 1) If the drag started outside the pinned apps list, it is a placeholder icon with a null
-    // tag.
-    // 2) If the drag started inside the pinned apps list, it is the icon for the app being dragged
-    // with the associated AppInfo tag.
-    // The icon is set invisible for the duration of the drag, creating a visual space for a drop.
-    // When the user is not dragging this member is null.
-    private ImageView mDragView;
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
-                int currentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                onUserSwitched(currentUserId);
-            } else if (Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {
-                UserHandle removedProfile = intent.getParcelableExtra(Intent.EXTRA_USER);
-                onManagedProfileRemoved(removedProfile);
-            }
-        }
-    };
-
-    // Layout params for the window that contains the anchor for the popup menus.
-    // We need to create a window for a popup menu because the NavBar window is too narrow and can't
-    // contain the menu.
-    private final WindowManager.LayoutParams mPopupAnchorLayoutParams;
-    // View that contains the anchor for popup menus. The view occupies the whole screen, and
-    // has a child that will be moved to make the menu to appear where we need it.
-    private final ViewGroup mPopupAnchor;
-    private final PopupMenu mPopupMenu;
-
-    /**
-     * True if popup menu code is busy with a popup operation.
-     * Attempting  to show a popup menu or to add menu items while it's returning true will
-     * corrupt/crash the app.
-     */
-    private boolean mIsPopupInUse = false;
-    private final int [] mClickedIconLocation = new int[2];
-
-    public NavigationBarApps(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        if (sAppsModel == null) {
-            sAppsModel = new NavigationBarAppsModel(context);
-        }
-        mPackageManager = context.getPackageManager();
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        mLayoutInflater = LayoutInflater.from(context);
-        mAppPackageMonitor = new AppPackageMonitor();
-
-        // Dragging an icon removes and adds back the dragged icon. Use the layout transitions to
-        // trigger animation. By default all transitions animate, so turn off the unneeded ones.
-        LayoutTransition transition = new LayoutTransition();
-        // Don't trigger on disappear. Adding the view will trigger the layout animation.
-        transition.disableTransitionType(LayoutTransition.DISAPPEARING);
-        // Don't animate the dragged icon itself.
-        transition.disableTransitionType(LayoutTransition.APPEARING);
-        // When an icon is dragged off the shelf, start sliding the other icons over immediately
-        // to match the parent view's animation.
-        transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
-        transition.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 0);
-        setLayoutTransition(transition);
-
-        TaskStackListener taskStackListener = new TaskStackListener();
-        IActivityManager iam = ActivityManagerNative.getDefault();
-        try {
-            iam.registerTaskStackListener(taskStackListener);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "registerTaskStackListener failed", e);
-        }
-
-        mPopupAnchorLayoutParams =
-                new WindowManager.LayoutParams(
-                        ViewGroup.LayoutParams.MATCH_PARENT,
-                        ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
-                        WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
-                        WindowManager.LayoutParams.FLAG_FULLSCREEN
-                                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
-                                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
-                        PixelFormat.TRANSLUCENT);
-        mPopupAnchorLayoutParams.setTitle("ShelfMenuAnchor");
-
-        mPopupAnchor = (ViewGroup) mLayoutInflater.inflate(R.layout.shelf_menu_anchor, null);
-
-        ImageView anchorButton =
-                (ImageView) mPopupAnchor.findViewById(R.id.shelf_menu_anchor_anchor);
-        mPopupMenu = new PopupMenu(context, anchorButton);
-    }
-
-    // Monitor that catches events like "app uninstalled".
-    private class AppPackageMonitor extends PackageMonitor {
-        @Override
-        public void onPackageRemoved(String packageName, int uid) {
-            postUnpinIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
-            super.onPackageRemoved(packageName, uid);
-        }
-
-        @Override
-        public void onPackageModified(String packageName) {
-            postUnpinIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
-            super.onPackageModified(packageName);
-        }
-
-        @Override
-        public void onPackagesAvailable(String[] packages) {
-            if (isReplacing()) {
-                UserHandle user = new UserHandle(getChangingUserId());
-
-                for (String packageName : packages) {
-                    postUnpinIfUnlauncheable(packageName, user);
-                }
-            }
-            super.onPackagesAvailable(packages);
-        }
-
-        @Override
-        public void onPackagesUnavailable(String[] packages) {
-            if (!isReplacing()) {
-                UserHandle user = new UserHandle(getChangingUserId());
-
-                for (String packageName : packages) {
-                    postUnpinIfUnlauncheable(packageName, user);
-                }
-            }
-            super.onPackagesUnavailable(packages);
-        }
-    }
-
-    private void postUnpinIfUnlauncheable(final String packageName, final UserHandle user) {
-        // This method doesn't necessarily get called in the main thread. Redirect the call into
-        // the main thread.
-        post(new Runnable() {
-            @Override
-            public void run() {
-                if (!isAttachedToWindow()) return;
-                unpinIfUnlauncheable(packageName, user);
-            }
-        });
-    }
-
-    private void unpinIfUnlauncheable(String packageName, UserHandle user) {
-        // Unpin icons for all apps that match a package that perhaps became unlauncheable.
-        boolean appsWereUnpinned = false;
-        for(int i = getChildCount() - 1; i >= 0; --i) {
-            View child = getChildAt(i);
-            AppButtonData appButtonData = (AppButtonData)child.getTag();
-            if (appButtonData == null) continue;  // Skip the drag placeholder.
-
-            if (!appButtonData.pinned) continue;
-
-            AppInfo appInfo = appButtonData.appInfo;
-            if (!appInfo.getUser().equals(user)) continue;
-
-            ComponentName appComponentName = appInfo.getComponentName();
-            if (!appComponentName.getPackageName().equals(packageName)) continue;
-
-            if (sAppsModel.resolveApp(appInfo) != null) {
-                continue;
-            }
-
-            appButtonData.pinned = false;
-            appsWereUnpinned = true;
-
-            if (appButtonData.isEmpty()) {
-                removeViewAt(i);
-            }
-        }
-        if (appsWereUnpinned) {
-            savePinnedApps();
-        }
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-      super.onAttachedToWindow();
-        // When an icon is dragged out of the pinned area this view's width changes, which causes
-        // the parent container's layout to change and the divider and recents icons to shift left.
-        // Animate the parent's CHANGING transition.
-        ViewGroup parent = (ViewGroup) getParent();
-        LayoutTransition transition = new LayoutTransition();
-        transition.disableTransitionType(LayoutTransition.APPEARING);
-        transition.disableTransitionType(LayoutTransition.DISAPPEARING);
-        transition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
-        transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
-        transition.enableTransitionType(LayoutTransition.CHANGING);
-        parent.setLayoutTransition(transition);
-
-        sAppsModel.setCurrentUser(ActivityManager.getCurrentUser());
-        recreatePinnedAppButtons();
-        updateRecentApps();
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_USER_SWITCHED);
-        filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
-        mContext.registerReceiver(mBroadcastReceiver, filter);
-
-        mAppPackageMonitor.register(mContext, null, UserHandle.ALL, true);
-        sAppsModel.addOnAppsChangedListener(this);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mContext.unregisterReceiver(mBroadcastReceiver);
-        mAppPackageMonitor.unregister();
-        sAppsModel.removeOnAppsChangedListener(this);
-    }
-
-    @Override
-    protected void onVisibilityChanged(View changedView, int visibility) {
-        super.onVisibilityChanged(changedView, visibility);
-        if (mIsPopupInUse && !isShown()) {
-            // Hide the popup if current view became invisible.
-            shutdownPopupMenu();
-        }
-    }
-
-    private void addAppButton(AppButtonData appButtonData) {
-        ImageView button = createAppButton();
-        updateApp(button, appButtonData);
-        addView(button);
-    }
-
-    private List<AppInfo> getPinnedApps() {
-        List<AppInfo> apps = new ArrayList<AppInfo>();
-        int childCount = getChildCount();
-        for (int i = 0; i != childCount; ++i) {
-            View child = getChildAt(i);
-            AppButtonData appButtonData = (AppButtonData)child.getTag();
-            if (appButtonData == null) continue;  // Skip the drag placeholder.
-            if(!appButtonData.pinned) continue;
-            apps.add(appButtonData.appInfo);
-        }
-        return apps;
-    }
-
-    /**
-     * Creates an ImageView icon for each pinned app. Removes any existing icons. May be called
-     * to synchronize the current view with the shared data mode.
-     */
-    private void recreatePinnedAppButtons() {
-        // Remove any existing icon buttons.
-        removeAllViews();
-
-        List<AppInfo> apps = sAppsModel.getApps();
-        int appCount = apps.size();
-        for (int i = 0; i < appCount; i++) {
-            AppInfo app = apps.get(i);
-            addAppButton(new AppButtonData(app, true /* pinned */));
-        }
-    }
-
-    /**
-     * Saves pinned apps stored in app icons into the data model.
-     */
-    private void savePinnedApps() {
-        sAppsModel.setApps(getPinnedApps());
-    }
-
-    /**
-     * Creates a new ImageView for an app, inflated from R.layout.navigation_bar_app_item.
-     */
-    private ImageView createAppButton() {
-        ImageView button = (ImageView) mLayoutInflater.inflate(
-                R.layout.navigation_bar_app_item, this, false /* attachToRoot */);
-        button.setOnHoverListener(new AppHoverListener());
-        button.setOnClickListener(new AppClickListener());
-        button.setOnContextClickListener(new AppContextClickListener());
-        // TODO: Ripple effect. Use either KeyButtonRipple or the default ripple background.
-        button.setOnLongClickListener(new AppLongClickListener());
-        button.setOnDragListener(new AppIconDragListener());
-        return button;
-    }
-
-    private class AppLongClickListener implements View.OnLongClickListener {
-        @Override
-        public boolean onLongClick(View v) {
-            mDragView = (ImageView) v;
-            AppButtonData appButtonData = (AppButtonData) v.getTag();
-            startAppDrag(mDragView, appButtonData.appInfo);
-            return true;
-        }
-    }
-
-    /**
-     * Returns the human-readable name for an activity's package or null.
-     * TODO: Cache the labels, perhaps in an LruCache.
-     */
-    @Nullable
-    private CharSequence getAppLabel(AppInfo appInfo) {
-        NavigationBarAppsModel.ResolvedApp resolvedApp = sAppsModel.resolveApp(appInfo);
-        if (resolvedApp == null) return null;
-
-        CharSequence unbadgedLabel = resolvedApp.ri.loadLabel(mPackageManager);
-        return mUserManager.getBadgedLabelForUser(unbadgedLabel, appInfo.getUser());
-    }
-
-    /** Helper function to start dragging an app icon (either pinned or recent). */
-    static void startAppDrag(ImageView icon, AppInfo appInfo) {
-        // The drag data is an Intent to launch the activity.
-        Intent mainIntent = Intent.makeMainActivity(appInfo.getComponentName());
-        UserManager userManager =
-                (UserManager) icon.getContext().getSystemService(Context.USER_SERVICE);
-        long userSerialNumber = userManager.getSerialNumberForUser(appInfo.getUser());
-        mainIntent.putExtra(EXTRA_PROFILE, userSerialNumber);
-        ClipData dragData = ClipData.newIntent("", mainIntent);
-        // Use the ImageView to create the shadow.
-        View.DragShadowBuilder shadow = new AppIconDragShadowBuilder(icon);
-        // Use a global drag because the icon might be dragged into the launcher.
-        icon.startDrag(dragData, shadow, null /* myLocalState */, View.DRAG_FLAG_GLOBAL);
-    }
-
-    @Override
-    public boolean dispatchDragEvent(DragEvent event) {
-        // ACTION_DRAG_ENTERED is handled by each individual app icon drag listener.
-        boolean childHandled = super.dispatchDragEvent(event);
-
-        // Other drag types are handled once per drag by this view. This is handled explicitly
-        // because attaching a DragListener to this ViewGroup does not work -- the DragListener in
-        // the children consumes the drag events.
-        boolean handled = false;
-        switch (event.getAction()) {
-            case DragEvent.ACTION_DRAG_STARTED:
-                handled = onDragStarted(event);
-                break;
-            case DragEvent.ACTION_DRAG_ENDED:
-                handled = onDragEnded();
-                break;
-            case DragEvent.ACTION_DROP:
-                handled = onDrop(event);
-                break;
-            case DragEvent.ACTION_DRAG_EXITED:
-                handled = onDragExited();
-                break;
-        }
-
-        return handled || childHandled;
-    }
-
-    /** Returns true if a drag should be handled. */
-    private static boolean canAcceptDrag(DragEvent event) {
-        // Poorly behaved apps might not provide a clip description.
-        if (event.getClipDescription() == null) {
-            return false;
-        }
-        // The event must contain an intent.
-        return event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_INTENT);
-    }
-
-    /**
-     * Sets up for a drag. Runs once per drag operation. Returns true if the data represents
-     * an app shortcut and will be accepted for a drop.
-     */
-    private boolean onDragStarted(DragEvent event) {
-        if (DEBUG) Slog.d(TAG, "onDragStarted");
-
-        // Ensure that an app shortcut is being dragged.
-        if (!canAcceptDrag(event)) {
-            return false;
-        }
-
-        // If there are no pinned apps this view will be collapsed, but the user still needs some
-        // empty space to use as a drag target.
-        if (getChildCount() == 0) {
-            mDragView = createPlaceholderDragView(0);
-        }
-
-        // If this is an existing icon being reordered, hide the app icon. The drag shadow will
-        // continue to draw.
-        if (mDragView != null) {
-            mDragView.setVisibility(View.INVISIBLE);
-        }
-
-        // Listen for the drag end event.
-        return true;
-    }
-
-    /**
-     * Creates a blank icon-sized View to create an empty space during a drag.
-     */
-    private ImageView createPlaceholderDragView(int index) {
-        ImageView button = createAppButton();
-        addView(button, index);
-        return button;
-    }
-
-    /**
-     * Returns initial index for a new app that doesn't exist in Shelf.
-     * Such apps get created by dragging them into Shelf from other apps or by dragging from Shelf
-     * and then back, or by removing from shelf as an intermediate step of pinning an app via menu.
-     * @param indexHint Initial proposed position for the item.
-     * @param isAppPinned True if the app being dragged is pinned.
-     */
-    int getNewAppIndex(int indexHint, boolean isAppPinned) {
-        int i;
-        if (isAppPinned) {
-            // For a pinned app, find the rightmost position to the left of the target that has a
-            // pinned app. We'll insert to the right of that position.
-            for (i = indexHint; i > 0; --i) {
-                View v = getChildAt(i - 1);
-                AppButtonData targetButtonData = (AppButtonData) v.getTag();
-                if (targetButtonData.pinned) break;
-            }
-        } else {
-            // For an unpinned app, find the leftmost position to the right of the target that has
-            // an unpinned app. We'll insert to the left of that position.
-            int childCount = getChildCount();
-            for (i = indexHint; i < childCount; ++i) {
-                View v = getChildAt(i);
-                AppButtonData targetButtonData = (AppButtonData) v.getTag();
-                if (!targetButtonData.pinned) break;
-            }
-        }
-        return i;
-    }
-
-    /**
-     * Handles a drag entering an existing icon. Not implemented in the drag listener because it
-     * needs to use LinearLayout/ViewGroup methods.
-     */
-    private void onDragEnteredIcon(View target) {
-        if (DEBUG) Slog.d(TAG, "onDragEntered " + indexOfChild(target));
-
-        int targetIndex = indexOfChild(target);
-
-        // If the drag didn't start from an existing shelf icon, add an invisible placeholder to
-        // create empty space for the user to drag into.
-        if (mDragView == null) {
-            mDragView = createPlaceholderDragView(getNewAppIndex(targetIndex, true));
-            return;
-        }
-
-        // If the user is dragging on top of the original icon location, do nothing.
-        if (target == mDragView) {
-            return;
-        }
-
-        // "Move" the dragged app by removing it and adding it back at the target location.
-        AppButtonData targetButtonData = (AppButtonData) target.getTag();
-        int dragViewIndex = indexOfChild(mDragView);
-        AppButtonData dragViewButtonData = (AppButtonData) mDragView.getTag();
-        // Calculating whether the dragged app is pinned. If the app came from outside if the shelf,
-        // in which case dragViewButtonData == null, it's a new app that we'll pin. Otherwise, the
-        // button data is defined, and we look whether that existing app is pinned.
-        boolean isAppPinned = dragViewButtonData == null || dragViewButtonData.pinned;
-
-        if (dragViewIndex == -1) {
-            // Drag view exists, but is not a child, which means that the drag has started at or
-            // already visited shelf, then left it, and now is entering it again.
-            targetIndex = getNewAppIndex(targetIndex, isAppPinned);
-        } else if (dragViewIndex < targetIndex) {
-            // The dragged app is currently at the left of the view where the drag is.
-            // We shouldn't allow moving a pinned app to the right of the unpinned app.
-            if (!targetButtonData.pinned && isAppPinned) return;
-        } else {
-            // The dragged app is currently at the right of the view where the drag is.
-            // We shouldn't allow moving a unpinned app to the left of the pinned app.
-            if (targetButtonData.pinned && !isAppPinned) return;
-        }
-
-        // This works, but is subtle:
-        // * If dragViewIndex > targetIndex then the dragged app is moving from right to left and
-        //   the dragged app will be added in front of the target.
-        // * If dragViewIndex < targetIndex then the dragged app is moving from left to right.
-        //   Removing the drag view will shift the later views one position to the left. Adding
-        //   the view at targetIndex will therefore place the app *after* the target.
-        removeView(mDragView);
-        addView(mDragView, targetIndex);
-    }
-
-    private boolean onDrop(DragEvent event) {
-        if (DEBUG) Slog.d(TAG, "onDrop");
-
-        // An earlier drag event might have canceled the drag. If so, there is nothing to do.
-        if (mDragView == null) {
-            return true;
-        }
-
-        boolean dragResult = true;
-        AppInfo appInfo = getAppFromDragEvent(event);
-        if (appInfo == null) {
-            // This wasn't a valid drop. Clean up the placeholder.
-            removePlaceholderDragViewIfNeeded();
-            dragResult = false;
-        } else if (mDragView.getTag() == null) {
-            // This is a drag that adds a new app. Convert the placeholder to a real icon.
-            updateApp(mDragView, new AppButtonData(appInfo, true /* pinned */));
-        }
-        endDrag();
-        return dragResult;
-    }
-
-    /** Cleans up at the end of a drag. */
-    private void endDrag() {
-        // An earlier drag event might have canceled the drag. If so, there is nothing to do.
-        if (mDragView == null) return;
-
-        mDragView.setVisibility(View.VISIBLE);
-        mDragView = null;
-        savePinnedApps();
-        // Add recent tasks to the info of the potentially added app.
-        updateRecentApps();
-    }
-
-    /** Returns an app info from a DragEvent, or null if the data wasn't valid. */
-    private AppInfo getAppFromDragEvent(DragEvent event) {
-        ClipData data = event.getClipData();
-        if (data == null) {
-            return null;
-        }
-        if (data.getItemCount() != 1) {
-            return null;
-        }
-        ClipData.Item item = data.getItemAt(0);
-        if (item == null) {
-            return null;
-        }
-        Intent intent = item.getIntent();
-        if (intent == null) {
-            return null;
-        }
-        long userSerialNumber = intent.getLongExtra(EXTRA_PROFILE, -1);
-        if (userSerialNumber == -1) {
-            return null;
-        }
-        UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
-        if (appUser == null) {
-            return null;
-        }
-        ComponentName componentName = intent.getComponent();
-        if (componentName == null) {
-            return null;
-        }
-        AppInfo appInfo = new AppInfo(componentName, appUser);
-        if (sAppsModel.resolveApp(appInfo) == null) {
-            return null;
-        }
-        return appInfo;
-    }
-
-    /** Updates the app at a given view index. */
-    private void updateApp(ImageView button, AppButtonData appButtonData) {
-        CharSequence appLabel = getAppLabel(appButtonData.appInfo);
-        button.setContentDescription(appLabel);
-
-        button.setTag(appButtonData);
-        new GetActivityIconTask(mPackageManager, button).execute(appButtonData);
-    }
-
-    /** Removes the empty placeholder view. */
-    private void removePlaceholderDragViewIfNeeded() {
-        // If the drag has ended already there is nothing to do.
-        if (mDragView == null) {
-            return;
-        }
-        removeView(mDragView);
-    }
-
-    /** Cleans up at the end of the drag. */
-    private boolean onDragEnded() {
-        if (DEBUG) Slog.d(TAG, "onDragEnded");
-        // If the icon wasn't already dropped into the app list then remove the placeholder.
-        removePlaceholderDragViewIfNeeded();
-        endDrag();
-        return true;
-    }
-
-    /** Handles the dragged icon exiting the bounds of this view during the drag. */
-    private boolean onDragExited() {
-        if (DEBUG) Slog.d(TAG, "onDragExited");
-        // Remove the placeholder. It will be added again if the user drags the icon back over
-        // the shelf.
-        removePlaceholderDragViewIfNeeded();
-        return true;
-    }
-
-    /** Drag listener for individual app icons. */
-    private class AppIconDragListener implements View.OnDragListener {
-        @Override
-        public boolean onDrag(View v, DragEvent event) {
-            switch (event.getAction()) {
-                case DragEvent.ACTION_DRAG_STARTED: {
-                    // Every button listens for drag events in order to detect enter/exit.
-                    return canAcceptDrag(event);
-                }
-                case DragEvent.ACTION_DRAG_ENTERED: {
-                    // Forward to NavigationBarApps.
-                    onDragEnteredIcon(v);
-                    return false;
-                }
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Brings the menu popup to closed state.
-     * Can be called at any stage of the asynchronous process of showing a menu.
-     */
-    private void shutdownPopupMenu() {
-        mWindowManager.removeView(mPopupAnchor);
-        mPopupMenu.dismiss();
-    }
-
-    /**
-     * Shows already prepopulated popup menu using appIcon for anchor location.
-     */
-    private void showPopupMenu(ImageView appIcon) {
-        // Movable view inside the popup anchor view. It serves as the actual anchor for the
-        // menu.
-        final ImageView anchorButton =
-                (ImageView) mPopupAnchor.findViewById(R.id.shelf_menu_anchor_anchor);
-        // Set same drawable as for the clicked button to have same size.
-        anchorButton.setImageDrawable(appIcon.getDrawable());
-
-        // Move the anchor button to the position of the app button.
-        appIcon.getLocationOnScreen(mClickedIconLocation);
-        anchorButton.setTranslationX(mClickedIconLocation[0]);
-        anchorButton.setTranslationY(mClickedIconLocation[1]);
-
-        final OnAttachStateChangeListener onAttachStateChangeListener =
-                new OnAttachStateChangeListener() {
-                    @Override
-                    public void onViewAttachedToWindow(View v) {
-                        mPopupMenu.show();
-                    }
-
-                    @Override
-                    public void onViewDetachedFromWindow(View v) {}
-                };
-        anchorButton.addOnAttachStateChangeListener(onAttachStateChangeListener);
-
-        mPopupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {
-            @Override
-            public void onDismiss(PopupMenu menu) {
-                // FYU: thorough testing for closing menu either by the user or via
-                // shutdownPopupMenu() called at various moments of the menu creation, revealed that
-                // 'onDismiss' is guaranteed to be called after each invocation of showPopupMenu.
-                mWindowManager.removeView(mPopupAnchor);
-                anchorButton.removeOnAttachStateChangeListener(onAttachStateChangeListener);
-                mPopupMenu.setOnDismissListener(null);
-                mPopupMenu.getMenu().clear();
-                mIsPopupInUse = false;
-            }
-        });
-
-        mWindowManager.addView(mPopupAnchor, mPopupAnchorLayoutParams);
-        mIsPopupInUse = true;
-    }
-
-    private void activateTask(int taskPersistentId) {
-        // Launch or bring the activity to front.
-        final IActivityManager iAm = ActivityManagerNative.getDefault();
-        try {
-            iAm.startActivityFromRecents(taskPersistentId, null /* options */);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Exception when activating a recent task", e);
-        } catch (IllegalArgumentException e) {
-            Slog.e(TAG, "Exception when activating a recent task", e);
-        }
-    }
-
-    /**
-     * Adds to the popup menu items for activating each of tasks in the specified list.
-     */
-    private void populateLaunchMenu(AppButtonData appButtonData) {
-        Menu menu = mPopupMenu.getMenu();
-        int taskCount = appButtonData.getTaskCount();
-        for (int i = 0; i < taskCount; ++i) {
-            final RecentTaskInfo taskInfo = appButtonData.tasks.get(i);
-            MenuItem item = menu.add(getActivityForTask(taskInfo).flattenToShortString());
-            item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                @Override
-                public boolean onMenuItemClick(MenuItem item) {
-                    activateTask(taskInfo.persistentId);
-                    return true;
-                }
-            });
-        }
-    }
-
-    /**
-     * Shows a task selection menu for clicked or hovered-over apps that have more than 1 running
-     * tasks.
-     */
-    void maybeShowLaunchMenu(ImageView appIcon) {
-        if (mIsPopupInUse) return;
-        AppButtonData appButtonData = (AppButtonData) appIcon.getTag();
-        if (appButtonData.getTaskCount() <= 1) return;
-
-        populateLaunchMenu(appButtonData);
-        showPopupMenu(appIcon);
-    }
-
-    /**
-     * A listener for hovering over an app icon.
-     */
-    private class AppHoverListener implements View.OnHoverListener {
-        private final long DELAY_MILLIS = 1000;
-        private Runnable mShowMenuCallback;
-
-        @Override
-        public boolean onHover(final View v, MotionEvent event) {
-            if (mShowMenuCallback == null) {
-                mShowMenuCallback = new Runnable() {
-                    @Override
-                    public void run() {
-                        maybeShowLaunchMenu((ImageView) v);
-                    }
-                };
-            }
-
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_HOVER_ENTER:
-                    postDelayed(mShowMenuCallback, DELAY_MILLIS);
-                    break;
-                case MotionEvent.ACTION_HOVER_EXIT:
-                    removeCallbacks(mShowMenuCallback);
-                    break;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * A click listener that launches an activity.
-     */
-    private class AppClickListener implements View.OnClickListener {
-        private void launchApp(AppInfo appInfo, View anchor) {
-            NavigationBarAppsModel.ResolvedApp resolvedApp = sAppsModel.resolveApp(appInfo);
-            if (resolvedApp == null) {
-                Toast.makeText(
-                        getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
-                return;
-            }
-
-            Intent launchIntent = resolvedApp.launchIntent;
-
-            // Play a scale-up animation while launching the activity.
-            // TODO: Consider playing a different animation, or no animation, if the activity is
-            // already open in a visible window. In that case we should move the task to front
-            // with minimal animation, perhaps using ActivityManager.moveTaskToFront().
-            Rect sourceBounds = new Rect();
-            anchor.getBoundsOnScreen(sourceBounds);
-            ActivityOptions opts =
-                    ActivityOptions.makeScaleUpAnimation(
-                            anchor, 0, 0, anchor.getWidth(), anchor.getHeight());
-            Bundle optsBundle = opts.toBundle();
-            launchIntent.setSourceBounds(sourceBounds);
-
-            mContext.startActivityAsUser(launchIntent, optsBundle, appInfo.getUser());
-        }
-
-        @Override
-        public void onClick(View v) {
-            AppButtonData appButtonData = (AppButtonData) v.getTag();
-
-            if (appButtonData.getTaskCount() == 0) {
-                launchApp(appButtonData.appInfo, v);
-            } else {
-                // Activate latest task.
-                activateTask(appButtonData.tasks.get(0).persistentId);
-
-                maybeShowLaunchMenu((ImageView) v);
-            }
-        }
-    }
-
-    /**
-     * Context click listener that shows app's context menu.
-     */
-    private class AppContextClickListener implements View.OnContextClickListener {
-        void updateState(ImageView appIcon) {
-            savePinnedApps();
-            if (DEBUG) {
-                AppButtonData appButtonData = (AppButtonData) appIcon.getTag();
-                new GetActivityIconTask(mPackageManager, appIcon).execute(appButtonData);
-            }
-        }
-
-        /**
-         * Adds to the popup menu items for pinning and unpinning the app in the shelf.
-         */
-        void populateContextMenu(final ImageView appIcon) {
-            final AppButtonData appButtonData = (AppButtonData) appIcon.getTag();
-            Menu menu = mPopupMenu.getMenu();
-            if (appButtonData.pinned) {
-                menu.add("Unpin").
-                        setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                            @Override
-                            public boolean onMenuItemClick(MenuItem item) {
-                                appButtonData.pinned = false;
-                                removeView(appIcon);
-                                if (!appButtonData.isEmpty()) {
-                                    // If the app has running tasks, re-add it to the end of shelf
-                                    // after unpinning.
-                                    addView(appIcon);
-                                }
-                                updateState(appIcon);
-                                return true;
-                            }
-                        });
-            } else {
-                menu.add("Pin").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                    @Override
-                    public boolean onMenuItemClick(MenuItem item) {
-                        appButtonData.pinned = true;
-                        removeView(appIcon);
-                        // Re-add the pinned icon to the end of the pinned list.
-                        addView(appIcon, getNewAppIndex(getChildCount(), true));
-                        updateState(appIcon);
-                        return true;
-                    }
-                });
-            }
-        }
-
-        @Override
-        public boolean onContextClick(View v) {
-            if (mIsPopupInUse) return true;
-            ImageView appIcon = (ImageView) v;
-            populateContextMenu(appIcon);
-            showPopupMenu(appIcon);
-            return true;
-        }
-    }
-
-    private void onUserSwitched(int currentUserId) {
-        sAppsModel.setCurrentUser(currentUserId);
-        recreatePinnedAppButtons();
-    }
-
-    private void onManagedProfileRemoved(UserHandle removedProfile) {
-        // Unpin apps from the removed profile.
-        boolean itemsWereUnpinned = false;
-        for(int i = getChildCount() - 1; i >= 0; --i) {
-            View view = getChildAt(i);
-            AppButtonData appButtonData = (AppButtonData)view.getTag();
-            if (appButtonData == null) return;  // Skip the drag placeholder.
-            if (!appButtonData.pinned) continue;
-            if (!appButtonData.appInfo.getUser().equals(removedProfile)) continue;
-
-            appButtonData.pinned = false;
-            itemsWereUnpinned = true;
-            if (appButtonData.isEmpty()) {
-                removeViewAt(i);
-            }
-        }
-        if (itemsWereUnpinned) {
-            savePinnedApps();
-        }
-    }
-
-    /**
-     * Returns app data for a button that matches the provided app info, if it exists, or null
-     * otherwise.
-     */
-    private AppButtonData findAppButtonData(AppInfo appInfo) {
-        int size = getChildCount();
-        for (int i = 0; i < size; ++i) {
-            View view = getChildAt(i);
-            AppButtonData appButtonData = (AppButtonData)view.getTag();
-            if (appButtonData == null) continue;  // Skip the drag placeholder.
-            if (appButtonData.appInfo.equals(appInfo)) {
-                return appButtonData;
-            }
-        }
-        return null;
-    }
-
-    private void updateTasks(List<RecentTaskInfo> tasks) {
-        // Remove tasks from all app buttons.
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            View view = getChildAt(i);
-            AppButtonData appButtonData = (AppButtonData)view.getTag();
-            if (appButtonData == null) return;  // Skip the drag placeholder.
-            appButtonData.clearTasks();
-        }
-
-        // Re-add tasks to app buttons, adding new buttons if needed.
-        int size = tasks.size();
-        for (int i = 0; i != size; ++i) {
-            RecentTaskInfo task = tasks.get(i);
-            AppInfo taskAppInfo = taskToAppInfo(task);
-            if (taskAppInfo == null) continue;
-            AppButtonData appButtonData = findAppButtonData(taskAppInfo);
-            if (appButtonData == null) {
-                appButtonData = new AppButtonData(taskAppInfo, false);
-                addAppButton(appButtonData);
-            }
-            appButtonData.addTask(task);
-        }
-
-        // Remove unpinned apps that now have no tasks.
-        for (int i = getChildCount() - 1; i >= 0; --i) {
-            View view = getChildAt(i);
-            AppButtonData appButtonData = (AppButtonData)view.getTag();
-            if (appButtonData == null) return;  // Skip the drag placeholder.
-            if (appButtonData.isEmpty()) {
-                removeViewAt(i);
-            }
-        }
-
-        if (DEBUG) {
-            for (int i = getChildCount() - 1; i >= 0; --i) {
-                View view = getChildAt(i);
-                AppButtonData appButtonData = (AppButtonData)view.getTag();
-                if (appButtonData == null) return;  // Skip the drag placeholder.
-                new GetActivityIconTask(mPackageManager, (ImageView )view).execute(appButtonData);
-
-            }
-        }
-    }
-
-    private void updateRecentApps() {
-        ActivityManager activityManager =
-                (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
-        // TODO: Should this be getRunningTasks?
-        List<RecentTaskInfo> recentTasks = activityManager.getRecentTasksForUser(
-                ActivityManager.getMaxAppRecentsLimitStatic(),
-                ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
-                        ActivityManager.RECENT_IGNORE_UNAVAILABLE |
-                        ActivityManager.RECENT_INCLUDE_PROFILES,
-                UserHandle.USER_CURRENT);
-        if (DEBUG) Slog.d(TAG, "Got recents " + recentTasks.size());
-        updateTasks(recentTasks);
-    }
-
-    private static ComponentName getActivityForTask(RecentTaskInfo task) {
-        // If the task was started from an alias, return the actual activity component that was
-        // initially started.
-        if (task.origActivity != null) {
-            return task.origActivity;
-        }
-        // Prefer the first activity of the task.
-        if (task.baseActivity != null) {
-            return task.baseActivity;
-        }
-        // Then goes the activity that started the task.
-        if (task.realActivity != null) {
-            return task.realActivity;
-        }
-        // This should not happen, but fall back to the base intent's activity component name.
-        return task.baseIntent.getComponent();
-    }
-
-    private ComponentName getLaunchComponentForPackage(String packageName, int userId) {
-        // This code is based on ApplicationPackageManager.getLaunchIntentForPackage.
-        PackageManager packageManager = mContext.getPackageManager();
-
-        // First see if the package has an INFO activity; the existence of
-        // such an activity is implied to be the desired front-door for the
-        // overall package (such as if it has multiple launcher entries).
-        Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
-        intentToResolve.addCategory(Intent.CATEGORY_INFO);
-        intentToResolve.setPackage(packageName);
-        List<ResolveInfo> ris = packageManager.queryIntentActivitiesAsUser(
-                intentToResolve, 0, userId);
-
-        // Otherwise, try to find a main launcher activity.
-        if (ris == null || ris.size() <= 0) {
-            // reuse the intent instance
-            intentToResolve.removeCategory(Intent.CATEGORY_INFO);
-            intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
-            intentToResolve.setPackage(packageName);
-            ris = packageManager.queryIntentActivitiesAsUser(intentToResolve, 0, userId);
-        }
-        if (ris == null || ris.size() <= 0) {
-            Slog.i(TAG, "Failed to build intent for " + packageName);
-            return null;
-        }
-        return new ComponentName(ris.get(0).activityInfo.packageName,
-                ris.get(0).activityInfo.name);
-    }
-
-    private AppInfo taskToAppInfo(RecentTaskInfo task) {
-        ComponentName componentName = getActivityForTask(task);
-        UserHandle taskUser = new UserHandle(task.userId);
-        AppInfo appInfo = new AppInfo(componentName, taskUser);
-
-        if (sAppsModel.resolveApp(appInfo) == null) {
-            // If task's activity is not launcheable, fall back to a launch component of the
-            // task's package.
-            ComponentName component = getLaunchComponentForPackage(
-                    componentName.getPackageName(), task.userId);
-
-            if (component == null) {
-                return null;
-            }
-
-            appInfo = new AppInfo(component, taskUser);
-        }
-
-        return appInfo;
-    }
-
-    /**
-     * A listener that updates the app buttons whenever the recents task stack changes.
-     */
-    private class TaskStackListener extends ITaskStackListener.Stub {
-        @Override
-        public void onTaskStackChanged() throws RemoteException {
-            // Post the message back to the UI thread.
-            post(new Runnable() {
-                @Override
-                public void run() {
-                    if (isAttachedToWindow()) {
-                        updateRecentApps();
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onActivityPinned() {
-        }
-    }
-
-    @Override
-    public void onPinnedAppsChanged() {
-        if (getPinnedApps().equals(sAppsModel.getApps())) return;
-        recreatePinnedAppButtons();
-        updateRecentApps();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
deleted file mode 100644
index 76a9798..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import android.app.AppGlobals;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Data model and controller for app icons appearing in the navigation bar. The data is stored on
- * disk in SharedPreferences. Each icon has a separate pref entry consisting of a flattened
- * ComponentName.
- */
-class NavigationBarAppsModel {
-    public interface OnAppsChangedListener {
-        void onPinnedAppsChanged();
-    }
-
-    public class ResolvedApp {
-        Intent launchIntent;
-        ResolveInfo ri;
-    }
-
-    private final static String TAG = "NavigationBarAppsModel";
-
-    // Default number of apps to load initially.
-    private final static int NUM_INITIAL_APPS = 4;
-
-    // Preferences file name.
-    private final static String SHARED_PREFERENCES_NAME = "com.android.systemui.navbarapps";
-
-    // Preference name for the version of the other preferences.
-    private final static String VERSION_PREF = "version";
-
-    // Current version number for preferences.
-    private final static int CURRENT_VERSION = 3;
-
-    // Preference name for the number of app icons.
-    private final static String APP_COUNT_PREF = "app_count";
-
-    // Preference name prefix for each app's info. The actual pref has an integer appended to it.
-    private final static String APP_PREF_PREFIX = "app_";
-
-    // User serial number prefix for each app's info. The actual pref has an integer appended to it.
-    private final static String APP_USER_PREFIX = "app_user_";
-
-    // Character separating current user serial number from the user-specific part of a pref.
-    // Example "22|app_user_2" - when logged as user with serial 22, we'll use this pref for the
-    // user serial of the third app of the logged-in user.
-    private final static char USER_SEPARATOR = '|';
-
-    private final Context mContext;
-    private final UserManager mUserManager;
-    private final SharedPreferences mPrefs;
-
-    // Apps are represented as an ordered list of app infos.
-    private List<AppInfo> mApps = new ArrayList<AppInfo>();
-
-    private List<OnAppsChangedListener> mOnAppsChangedListeners =
-            new ArrayList<OnAppsChangedListener>();
-
-    // Id of the current user.
-    private int mCurrentUserId = -1;
-
-    // Serial number of the current user.
-    private long mCurrentUserSerialNumber = -1;
-
-    public NavigationBarAppsModel(Context context) {
-        mContext = context;
-        mPrefs = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-
-        int version = mPrefs.getInt(VERSION_PREF, -1);
-        if (version != CURRENT_VERSION) {
-            // Since the data format changed, clean everything.
-            SharedPreferences.Editor edit = mPrefs.edit();
-            edit.clear();
-            edit.putInt(VERSION_PREF, CURRENT_VERSION);
-            edit.apply();
-        }
-    }
-
-    @VisibleForTesting
-    protected IPackageManager getPackageManager() {
-        return AppGlobals.getPackageManager();
-    }
-
-    // Returns a resolved app info for a given app info, or null if the app info is unlauncheable.
-    public ResolvedApp resolveApp(AppInfo appInfo) {
-        ComponentName component = appInfo.getComponentName();
-        int appUserId = appInfo.getUser().getIdentifier();
-
-        if (mCurrentUserId != appUserId) {
-            // Check if app user is a profile of current user and the app user is enabled.
-            UserInfo appUserInfo = mUserManager.getUserInfo(appUserId);
-            UserInfo currentUserInfo = mUserManager.getUserInfo(mCurrentUserId);
-            if (appUserInfo == null || currentUserInfo == null
-                    || appUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID
-                    || appUserInfo.profileGroupId != currentUserInfo.profileGroupId
-                    || !appUserInfo.isEnabled()) {
-                Slog.e(TAG, "User " + appUserId +
-                        " is is not a profile of the current user, or is disabled.");
-                return null;
-            }
-        }
-
-        // This code is based on LauncherAppsService.startActivityAsUser code.
-        Intent launchIntent = new Intent(Intent.ACTION_MAIN);
-        launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        launchIntent.setPackage(component.getPackageName());
-
-        try {
-            ActivityInfo info = getPackageManager().getActivityInfo(component, 0, appUserId);
-            if (info == null) {
-                Slog.e(TAG, "Activity " + component + " is not installed.");
-                return null;
-            }
-
-            if (!info.exported) {
-                Slog.e(TAG, "Activity " + component + " doesn't have 'exported' attribute.");
-                return null;
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to get activity info for " + component, e);
-            return null;
-        }
-
-        // Check that the component actually has Intent.CATEGORY_LAUNCHER
-        // as calling startActivityAsUser ignores the category and just
-        // resolves based on the component if present.
-        List<ResolveInfo> apps = mContext.getPackageManager().queryIntentActivitiesAsUser(launchIntent,
-                0 /* flags */, appUserId);
-        final int size = apps.size();
-        for (int i = 0; i < size; ++i) {
-            ResolveInfo ri = apps.get(i);
-            ActivityInfo activityInfo = ri.activityInfo;
-            if (activityInfo.packageName.equals(component.getPackageName()) &&
-                    activityInfo.name.equals(component.getClassName())) {
-                // Found an activity with category launcher that matches
-                // this component so ok to launch.
-                launchIntent.setComponent(component);
-                ResolvedApp resolvedApp = new ResolvedApp();
-                resolvedApp.launchIntent = launchIntent;
-                resolvedApp.ri = ri;
-                return resolvedApp;
-            }
-        }
-
-        Slog.i(TAG, "Activity doesn't have category Intent.CATEGORY_LAUNCHER " + component);
-        return null;
-    }
-
-    public void addOnAppsChangedListener(OnAppsChangedListener listener) {
-        mOnAppsChangedListeners.add(listener);
-    }
-
-    public void removeOnAppsChangedListener(OnAppsChangedListener listener) {
-        mOnAppsChangedListeners.remove(listener);
-    }
-
-    /**
-     * Reinitializes the model for a new user.
-     */
-    public void setCurrentUser(int userId) {
-        mCurrentUserId = userId;
-        mCurrentUserSerialNumber = mUserManager.getSerialNumberForUser(new UserHandle(userId));
-
-        mApps.clear();
-
-        int appCount = mPrefs.getInt(userPrefixed(APP_COUNT_PREF), -1);
-        if (appCount >= 0) {
-            loadAppsFromPrefs(appCount);
-        } else {
-            // We switched to this user for the first time ever. This is a good opportunity to clean
-            // prefs for users deleted in the past.
-            removePrefsForDeletedUsers();
-
-            addDefaultApps();
-        }
-    }
-
-    /**
-     * Removes prefs for users that don't exist on the device.
-     */
-    private void removePrefsForDeletedUsers() {
-        // Build a set of string representations of serial numbers of the device users.
-        final List<UserInfo> users = mUserManager.getUsers();
-        final int userCount = users.size();
-
-        final Set<String> userSerials = new HashSet<String> ();
-
-        for (int i = 0; i < userCount; ++i) {
-            userSerials.add(Long.toString(users.get(i).serialNumber));
-        }
-
-        // Walk though all prefs and delete ones which user is not in the string set.
-        final Map<String, ?> allPrefs = mPrefs.getAll();
-        final SharedPreferences.Editor edit = mPrefs.edit();
-
-        for (Map.Entry<String, ?> pref : allPrefs.entrySet()) {
-            final String key = pref.getKey();
-            if (key.equals(VERSION_PREF)) continue;
-
-            final int userSeparatorPos = key.indexOf(USER_SEPARATOR);
-
-            if (userSeparatorPos < 0) {
-                // Removing anomalous pref with no user.
-                edit.remove(key);
-                continue;
-            }
-
-            final String prefUserSerial = key.substring(0, userSeparatorPos);
-
-            if (!userSerials.contains(prefUserSerial)) {
-                // Removes pref for a not existing user.
-                edit.remove(key);
-                continue;
-            }
-        }
-
-        edit.apply();
-    }
-
-    /** Returns the list of apps. */
-    public List<AppInfo> getApps() {
-        return mApps;
-    }
-
-    /** Sets the list of apps and saves it. */
-    public void setApps(List<AppInfo> apps) {
-        mApps = apps;
-        savePrefs();
-
-        int size = mOnAppsChangedListeners.size();
-        for (int i = 0; i < size; ++i) {
-            mOnAppsChangedListeners.get(i).onPinnedAppsChanged();
-        }
-    }
-
-    /** Saves the current model to disk. */
-    private void savePrefs() {
-        SharedPreferences.Editor edit = mPrefs.edit();
-        int appCount = mApps.size();
-        edit.putInt(userPrefixed(APP_COUNT_PREF), appCount);
-        for (int i = 0; i < appCount; i++) {
-            final AppInfo appInfo = mApps.get(i);
-            String componentNameString = appInfo.getComponentName().flattenToString();
-            edit.putString(prefNameForApp(i), componentNameString);
-            long userSerialNumber = mUserManager.getSerialNumberForUser(appInfo.getUser());
-            edit.putLong(prefUserForApp(i), userSerialNumber);
-        }
-        // Start an asynchronous disk write.
-        edit.apply();
-    }
-
-    /** Loads AppInfo from prefs. Returns null if something is wrong. */
-    private AppInfo loadAppFromPrefs(int index) {
-        String prefValue = mPrefs.getString(prefNameForApp(index), null);
-        if (prefValue == null) {
-            Slog.w(TAG, "Couldn't find pref " + prefNameForApp(index));
-            return null;
-        }
-        ComponentName componentName = ComponentName.unflattenFromString(prefValue);
-        if (componentName == null) {
-            Slog.w(TAG, "Invalid component name " + prefValue);
-            return null;
-        }
-        long userSerialNumber = mPrefs.getLong(prefUserForApp(index), -1);
-        if (userSerialNumber == -1) {
-            Slog.w(TAG, "Couldn't find pref " + prefUserForApp(index));
-            return null;
-        }
-        UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
-        if (appUser == null) {
-            Slog.w(TAG, "No user for serial " + userSerialNumber);
-            return null;
-        }
-        AppInfo appInfo = new AppInfo(componentName, appUser);
-        if (resolveApp(appInfo) == null) {
-            return null;
-        }
-        return appInfo;
-    }
-
-    /** Loads the list of apps from SharedPreferences. */
-    private void loadAppsFromPrefs(int appCount) {
-        for (int i = 0; i < appCount; i++) {
-            AppInfo appInfo = loadAppFromPrefs(i);
-            if (appInfo != null) {
-                mApps.add(appInfo);
-            }
-        }
-
-        if (appCount != mApps.size()) savePrefs();
-    }
-
-    /** Adds the first few apps from the owner profile. Used for demo purposes. */
-    private void addDefaultApps() {
-        // Get a list of all app activities.
-        final Intent queryIntent = new Intent(Intent.ACTION_MAIN, null);
-        queryIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-
-        final List<ResolveInfo> apps = mContext.getPackageManager().queryIntentActivitiesAsUser(
-                queryIntent, 0 /* flags */, mCurrentUserId);
-        final int appCount = apps.size();
-        for (int i = 0; i < NUM_INITIAL_APPS && i < appCount; i++) {
-            ResolveInfo ri = apps.get(i);
-            ComponentName componentName = new ComponentName(
-                    ri.activityInfo.packageName, ri.activityInfo.name);
-            mApps.add(new AppInfo(componentName, new UserHandle(mCurrentUserId)));
-        }
-
-        savePrefs();
-    }
-
-    /** Returns a pref prefixed with the serial number of the current user. */
-    private String userPrefixed(String pref) {
-        return Long.toString(mCurrentUserSerialNumber) + USER_SEPARATOR + pref;
-    }
-
-    /** Returns the pref name for the app at a given index. */
-    private String prefNameForApp(int index) {
-        return userPrefixed(APP_PREF_PREFIX + Integer.toString(index));
-    }
-
-    /** Returns the pref name for the app's user at a given index. */
-    private String prefUserForApp(int index) {
-        return userPrefixed(APP_USER_PREFIX + Integer.toString(index));
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index abe357a..786e64d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -27,6 +27,7 @@
 import android.view.ViewConfiguration;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.stackdivider.Divider;
@@ -42,16 +43,20 @@
         implements TunerService.Tunable {
 
     private static final String KEY_DOCK_WINDOW_GESTURE = "overview_nav_bar_gesture";
+    /**
+     * When dragging from the navigation bar, we drag in recents.
+     */
+    public static final int DRAG_MODE_NONE = -1;
 
     /**
      * When dragging from the navigation bar, we drag in recents.
      */
-    private static final int DRAG_MODE_RECENTS = 0;
+    public static final int DRAG_MODE_RECENTS = 0;
 
     /**
      * When dragging from the navigation bar, we drag the divider.
      */
-    private static final int DRAG_MODE_DIVIDER = 1;
+    public static final int DRAG_MODE_DIVIDER = 1;
 
     private RecentsComponent mRecentsComponent;
     private Divider mDivider;
@@ -207,16 +212,14 @@
                         < mContext.getResources().getDisplayMetrics().widthPixels / 2) {
                     createMode = ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
                 }
-                boolean docked = mRecentsComponent.dockTopTask(dragMode == DRAG_MODE_RECENTS,
-                        createMode, initialBounds);
+                boolean docked = mRecentsComponent.dockTopTask(dragMode, createMode, initialBounds);
                 if (docked) {
                     mDragMode = dragMode;
                     if (mDragMode == DRAG_MODE_DIVIDER) {
-                        mDivider.getView().startDragging(false /* animate */);
+                        mDivider.getView().startDragging(false /* animate */, true /* touching*/);
                     }
                     mDockWindowTouchSlopExceeded = true;
-                    MetricsLogger.action(mContext,
-                            MetricsLogger.ACTION_WINDOW_DOCK_SWIPE);
+                    MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_SWIPE);
 
                     return true;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index b8ae81f..ba08ee7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -14,6 +14,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -24,6 +25,7 @@
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.Space;
 import com.android.systemui.R;
 import com.android.systemui.tuner.TunerService;
@@ -36,20 +38,20 @@
 
     public static final String NAV_BAR_VIEWS = "sysui_nav_bar";
 
-    private static final String MENU_IME = "menu_ime";
-    private static final String BACK = "back";
-    private static final String HOME = "home";
-    private static final String RECENT = "recent";
-    private static final String NAVSPACE = "space";
+    protected static final String MENU_IME = "menu_ime";
+    protected static final String BACK = "back";
+    protected static final String HOME = "home";
+    protected static final String RECENT = "recent";
+    protected static final String NAVSPACE = "space";
 
     public static final String GRAVITY_SEPARATOR = ";";
     public static final String BUTTON_SEPARATOR = ",";
 
-    private final LayoutInflater mLayoutInflater;
-    private final LayoutInflater mLandscapeInflater;
+    protected final LayoutInflater mLayoutInflater;
+    protected final LayoutInflater mLandscapeInflater;
 
-    private FrameLayout mRot0;
-    private FrameLayout mRot90;
+    protected FrameLayout mRot0;
+    protected FrameLayout mRot90;
     private SparseArray<ButtonDispatcher> mButtonDispatchers;
     private String mCurrentLayout;
 
@@ -71,7 +73,7 @@
         inflateLayout(getDefaultLayout());
     }
 
-    private String getDefaultLayout() {
+    protected String getDefaultLayout() {
         return mContext.getString(R.string.config_navBarLayout);
     }
 
@@ -108,12 +110,10 @@
     }
 
     private void initiallyFill(ButtonDispatcher buttonDispatcher) {
-        addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.start_group));
+        addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.ends_group));
         addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.center_group));
-        addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.end_group));
-        addAll(buttonDispatcher, (ViewGroup) mRot90.findViewById(R.id.start_group));
+        addAll(buttonDispatcher, (ViewGroup) mRot90.findViewById(R.id.ends_group));
         addAll(buttonDispatcher, (ViewGroup) mRot90.findViewById(R.id.center_group));
-        addAll(buttonDispatcher, (ViewGroup) mRot90.findViewById(R.id.end_group));
     }
 
     private void addAll(ButtonDispatcher buttonDispatcher, ViewGroup parent) {
@@ -129,24 +129,33 @@
         }
     }
 
-    private void inflateLayout(String newLayout) {
+    protected void inflateLayout(String newLayout) {
         mCurrentLayout = newLayout;
-        String[] sets = newLayout.split(GRAVITY_SEPARATOR);
+        String[] sets = newLayout.split(GRAVITY_SEPARATOR, 3);
         String[] start = sets[0].split(BUTTON_SEPARATOR);
         String[] center = sets[1].split(BUTTON_SEPARATOR);
         String[] end = sets[2].split(BUTTON_SEPARATOR);
-        inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.start_group),
-                (ViewGroup) mRot0.findViewById(R.id.start_group_lightsout), false);
-        inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.start_group),
-                (ViewGroup) mRot90.findViewById(R.id.start_group_lightsout), true);
+        inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.ends_group),
+                (ViewGroup) mRot0.findViewById(R.id.ends_group_lightsout), false);
+        inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.ends_group),
+                (ViewGroup) mRot90.findViewById(R.id.ends_group_lightsout), true);
+
         inflateButtons(center, (ViewGroup) mRot0.findViewById(R.id.center_group),
-                (ViewGroup) mRot0.findViewById(R.id.start_group_lightsout), false);
+                (ViewGroup) mRot0.findViewById(R.id.center_group_lightsout), false);
         inflateButtons(center, (ViewGroup) mRot90.findViewById(R.id.center_group),
-                (ViewGroup) mRot90.findViewById(R.id.start_group_lightsout), true);
-        inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.end_group),
-                (ViewGroup) mRot0.findViewById(R.id.start_group_lightsout), false);
-        inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.end_group),
-                (ViewGroup) mRot90.findViewById(R.id.start_group_lightsout), true);
+                (ViewGroup) mRot90.findViewById(R.id.center_group_lightsout), true);
+
+        addGravitySpacer((LinearLayout) mRot0.findViewById(R.id.ends_group));
+        addGravitySpacer((LinearLayout) mRot90.findViewById(R.id.ends_group));
+
+        inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.ends_group),
+                (ViewGroup) mRot0.findViewById(R.id.ends_group_lightsout), false);
+        inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.ends_group),
+                (ViewGroup) mRot90.findViewById(R.id.ends_group_lightsout), true);
+    }
+
+    private void addGravitySpacer(LinearLayout layout) {
+        layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1));
     }
 
     private void inflateButtons(String[] buttons, ViewGroup parent, ViewGroup lightsOutParent,
@@ -157,6 +166,8 @@
     }
 
     private void copyToLightsout(View view, ViewGroup lightsOutParent) {
+        if (view == null) return;
+
         if (view instanceof FrameLayout) {
             // The only ViewGroup we support in here is a FrameLayout, so copy those manually.
             FrameLayout original = (FrameLayout) view;
@@ -187,46 +198,52 @@
     }
 
     private ViewGroup.LayoutParams copy(ViewGroup.LayoutParams layoutParams) {
+        if (layoutParams instanceof LinearLayout.LayoutParams) {
+            return new LinearLayout.LayoutParams(layoutParams.width, layoutParams.height,
+                    ((LinearLayout.LayoutParams) layoutParams).weight);
+        }
         return new LayoutParams(layoutParams.width, layoutParams.height);
     }
 
-    private View inflateButton(String button, ViewGroup parent, boolean landscape) {
-        View v = null;
+    @Nullable
+    protected View inflateButton(String button, ViewGroup parent, boolean landscape) {
+        View v;
+        LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
         if (HOME.equals(button)) {
-            v = (landscape ? mLandscapeInflater : mLayoutInflater)
-                    .inflate(R.layout.home, parent, false);
+            v = inflater.inflate(R.layout.home, parent, false);
             if (landscape && isSw600Dp()) {
                 setupLandButton(v);
             }
         } else if (BACK.equals(button)) {
-            v = (landscape ? mLandscapeInflater : mLayoutInflater)
-                    .inflate(R.layout.back, parent, false);
+            v = inflater.inflate(R.layout.back, parent, false);
             if (landscape && isSw600Dp()) {
                 setupLandButton(v);
             }
         } else if (RECENT.equals(button)) {
-            v = (landscape ? mLandscapeInflater : mLayoutInflater)
-                    .inflate(R.layout.recent_apps, parent, false);
+            v = inflater.inflate(R.layout.recent_apps, parent, false);
             if (landscape && isSw600Dp()) {
                 setupLandButton(v);
             }
         } else if (MENU_IME.equals(button)) {
-            v = (landscape ? mLandscapeInflater : mLayoutInflater)
-                    .inflate(R.layout.menu_ime, parent, false);
+            v = inflater.inflate(R.layout.menu_ime, parent, false);
         } else if (NAVSPACE.equals(button)) {
-            v = (landscape ? mLandscapeInflater : mLayoutInflater)
-                    .inflate(R.layout.nav_key_space, parent, false);
+            v = inflater.inflate(R.layout.nav_key_space, parent, false);
         } else {
-            throw new IllegalArgumentException("Unknown button " + button);
+            return null;
         }
+
         parent.addView(v);
+        addToDispatchers(v);
+        return v;
+    }
+
+    private void addToDispatchers(View v) {
         if (mButtonDispatchers != null) {
             final int indexOfKey = mButtonDispatchers.indexOfKey(v.getId());
             if (indexOfKey >= 0) {
                 mButtonDispatchers.valueAt(indexOfKey).addView(v);
             }
         }
-        return v;
     }
 
     private boolean isSw600Dp() {
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 839b579..d86629f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -263,11 +263,6 @@
         return mButtonDisatchers.get(R.id.ime_switcher);
     }
 
-    @Nullable
-    public View getAppShelf() {
-        return getCurrentView().findViewById(R.id.app_shelf);
-    }
-
     private void getCarModeIcons(Context ctx) {
         mBackCarModeIcon = ctx.getDrawable(R.drawable.ic_sysbar_back_carmode);
         mBackLandCarModeIcon = mBackCarModeIcon;
@@ -395,12 +390,6 @@
         getBackButton().setVisibility(disableBack      ? View.INVISIBLE : View.VISIBLE);
         getHomeButton().setVisibility(disableHome      ? View.INVISIBLE : View.VISIBLE);
         getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
-
-        // The app shelf, if it exists, follows the visibility of the home button.
-        View appShelf = getAppShelf();
-        if (appShelf != null) {
-            appShelf.setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
-        }
     }
 
     private boolean inLockTask() {
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 ba20679..8e89efd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -39,11 +39,11 @@
 import android.view.ViewTreeObserver;
 import android.view.WindowInsets;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
 import android.widget.TextView;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.DejankUtils;
@@ -57,6 +57,7 @@
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.GestureRecorder;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.StatusBarState;
@@ -104,7 +105,6 @@
     private View mQsNavbarScrim;
     private NotificationsQuickSettingsContainer mNotificationContainerParent;
     private NotificationStackScrollLayout mNotificationStackScroller;
-    private int mNotificationTopPadding;
     private boolean mAnimateNextTopPaddingChange;
 
     private int mTrackingPointer;
@@ -151,9 +151,6 @@
     private int mUnlockMoveDistance;
     private float mEmptyDragAmount;
 
-    private Interpolator mFastOutSlowInInterpolator;
-    private Interpolator mFastOutLinearInterpolator;
-    private Interpolator mDozeAnimationInterpolator;
     private ObjectAnimator mClockAnimator;
     private int mClockAnimationTarget = -1;
     private int mTopPaddingAdjustment;
@@ -253,12 +250,6 @@
         mNotificationStackScroller.setOverscrollTopChangedListener(this);
         mNotificationStackScroller.setOnEmptySpaceClickListener(this);
         mNotificationStackScroller.setScrollView(mScrollView);
-        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
-                android.R.interpolator.fast_out_slow_in);
-        mFastOutLinearInterpolator = AnimationUtils.loadInterpolator(getContext(),
-                android.R.interpolator.fast_out_linear_in);
-        mDozeAnimationInterpolator = AnimationUtils.loadInterpolator(getContext(),
-                android.R.interpolator.linear_out_slow_in);
         mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
         mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
         mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext());
@@ -281,8 +272,6 @@
     @Override
     protected void loadDimens() {
         super.loadDimens();
-        mNotificationTopPadding = getResources().getDimensionPixelSize(
-                R.dimen.notifications_top_padding);
         mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.4f);
         mStatusBarMinHeight = getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.status_bar_height);
@@ -371,7 +360,7 @@
         }
         mQsSizeChangeAnimator = ValueAnimator.ofInt(oldHeight, newHeight);
         mQsSizeChangeAnimator.setDuration(300);
-        mQsSizeChangeAnimator.setInterpolator(mFastOutSlowInInterpolator);
+        mQsSizeChangeAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         mQsSizeChangeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
@@ -400,8 +389,8 @@
         if (mStatusBarState != StatusBarState.KEYGUARD) {
             int bottom = mHeader.getCollapsedHeight();
             stackScrollerPadding = mStatusBarState == StatusBarState.SHADE
-                    ? bottom + mQsPeekHeight + mNotificationTopPadding
-                    : mKeyguardStatusBar.getHeight() + mNotificationTopPadding;
+                    ? bottom + mQsPeekHeight
+                    : mKeyguardStatusBar.getHeight();
             mTopPaddingAdjustment = 0;
         } else {
             mClockPositionAlgorithm.setup(
@@ -433,8 +422,8 @@
     public int computeMaxKeyguardNotifications(int maximum) {
         float minPadding = mClockPositionAlgorithm.getMinStackScrollerPadding(getHeight(),
                 mKeyguardStatusView.getHeight());
-        int keyguardPadding = getResources().getDimensionPixelSize(
-                R.dimen.notification_padding_dimmed);
+        int notificationPadding = Math.max(1, getResources().getDimensionPixelSize(
+                R.dimen.notification_divider_height));
         final int overflowheight = getResources().getDimensionPixelSize(
                 R.dimen.notification_summary_height);
         float bottomStackSize = mNotificationStackScroller.getKeyguardBottomStackSize();
@@ -446,7 +435,7 @@
             if (!(child instanceof ExpandableNotificationRow)) {
                 continue;
             }
-            availableSpace -= child.getMinHeight() + keyguardPadding;
+            availableSpace -= child.getMinHeight() + notificationPadding;
             if (availableSpace >= 0 && count < maximum) {
                 count++;
             } else {
@@ -471,7 +460,7 @@
                 }
                 mClockAnimator = ObjectAnimator
                         .ofFloat(mKeyguardStatusView, View.Y, mClockAnimationTarget);
-                mClockAnimator.setInterpolator(mFastOutSlowInInterpolator);
+                mClockAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
                 mClockAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
                 mClockAnimator.addListener(new AnimatorListenerAdapter() {
                     @Override
@@ -1107,7 +1096,7 @@
                     .translationY(0f)
                     .setStartDelay(delay)
                     .setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE)
-                    .setInterpolator(mFastOutSlowInInterpolator)
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                     .start();
             mQsContainer.setY(-mQsContainer.getHeight());
             mQsContainerAnimator = ObjectAnimator.ofFloat(mQsContainer, View.TRANSLATION_Y,
@@ -1116,7 +1105,7 @@
                             - mQsContainer.getTop());
             mQsContainerAnimator.setStartDelay(delay);
             mQsContainerAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
-            mQsContainerAnimator.setInterpolator(mFastOutSlowInInterpolator);
+            mQsContainerAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
             mQsContainerAnimator.addListener(mAnimateHeaderSlidingInListener);
             mQsContainerAnimator.start();
             mQsContainer.addOnLayoutChangeListener(mQsContainerAnimatorUpdater);
@@ -1138,7 +1127,7 @@
         mHeader.animate().y(-mHeader.getHeight())
                 .setStartDelay(0)
                 .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
-                .setInterpolator(mFastOutSlowInInterpolator)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 .setListener(new AnimatorListenerAdapter() {
                     @Override
                     public void onAnimationEnd(Animator animation) {
@@ -1152,7 +1141,7 @@
                 .y(-mQsContainer.getHeight())
                 .setStartDelay(0)
                 .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
-                .setInterpolator(mFastOutSlowInInterpolator)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 .start();
     }
 
@@ -1174,7 +1163,7 @@
         anim.setDuration(mStatusBar.isKeyguardFadingAway()
                 ? mStatusBar.getKeyguardFadingAwayDuration() / 2
                 : StackStateAnimator.ANIMATION_DURATION_STANDARD);
-        anim.setInterpolator(mDozeAnimationInterpolator);
+        anim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -1199,7 +1188,7 @@
         ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
         anim.addUpdateListener(mStatusBarAnimateAlphaListener);
         anim.setDuration(duration);
-        anim.setInterpolator(mDozeAnimationInterpolator);
+        anim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
         anim.start();
     }
 
@@ -1218,7 +1207,7 @@
                     .alpha(0f)
                     .setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
                     .setDuration(mStatusBar.getKeyguardFadingAwayDuration() / 2)
-                    .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                    .setInterpolator(Interpolators.ALPHA_OUT)
                     .withEndAction(mAnimateKeyguardBottomAreaInvisibleEndRunnable)
                     .start();
         } else if (statusBarState == StatusBarState.KEYGUARD
@@ -1245,7 +1234,7 @@
                     .alpha(0f)
                     .setStartDelay(0)
                     .setDuration(160)
-                    .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                    .setInterpolator(Interpolators.ALPHA_OUT)
                     .withEndAction(mAnimateKeyguardStatusViewInvisibleEndRunnable);
             if (keyguardFadingAway) {
                 mKeyguardStatusView.animate()
@@ -1263,7 +1252,7 @@
                     .alpha(1f)
                     .setStartDelay(0)
                     .setDuration(320)
-                    .setInterpolator(PhoneStatusBar.ALPHA_IN)
+                    .setInterpolator(Interpolators.ALPHA_IN)
                     .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable);
         } else if (statusBarState == StatusBarState.KEYGUARD) {
             mKeyguardStatusView.animate().cancel();
@@ -1380,8 +1369,7 @@
             // on Keyguard, maxQs denotes the top padding from the quick settings panel. We need to
             // take the maximum and linearly interpolate with the panel expansion for a nice motion.
             int maxNotifications = mClockPositionResult.stackScrollerPadding
-                    - mClockPositionResult.stackScrollerPaddingAdjustment
-                    - mNotificationTopPadding;
+                    - mClockPositionResult.stackScrollerPaddingAdjustment;
             int maxQs = getTempQsMaxExpansion();
             int max = mStatusBarState == StatusBarState.KEYGUARD
                     ? Math.max(maxNotifications, maxQs)
@@ -1395,7 +1383,7 @@
             // We can only do the smoother transition on Keyguard when we also are not collapsing
             // from a scrolled quick settings.
             return interpolate(getQsExpansionFraction(),
-                    mNotificationStackScroller.getIntrinsicPadding() - mNotificationTopPadding,
+                    mNotificationStackScroller.getIntrinsicPadding(),
                     mQsMaxExpansionHeight);
         } else {
             return mQsExpansionHeight;
@@ -1625,15 +1613,13 @@
             maxQsHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
         }
         float totalHeight = Math.max(
-                maxQsHeight + mNotificationStackScroller.getNotificationTopPadding(),
-                mStatusBarState == StatusBarState.KEYGUARD
+                maxQsHeight, mStatusBarState == StatusBarState.KEYGUARD
                         ? mClockPositionResult.stackScrollerPadding - mTopPaddingAdjustment
                         : 0)
                 + notificationHeight;
         if (totalHeight > mNotificationStackScroller.getHeight()) {
             float fullyCollapsedHeight = maxQsHeight
                     + mNotificationStackScroller.getMinStackHeight()
-                    + mNotificationStackScroller.getNotificationTopPadding()
                     - getScrollViewScrollY();
             totalHeight = Math.max(fullyCollapsedHeight, mNotificationStackScroller.getHeight());
         }
@@ -1680,14 +1666,14 @@
             boolean active = getMaxPanelHeight() - getExpandedHeight() > mUnlockMoveDistance;
             KeyguardAffordanceView lockIcon = mKeyguardBottomArea.getLockIcon();
             if (active && !mUnlockIconActive && mTracking) {
-                lockIcon.setImageAlpha(1.0f, true, 150, mFastOutLinearInterpolator, null);
+                lockIcon.setImageAlpha(1.0f, true, 150, Interpolators.FAST_OUT_LINEAR_IN, null);
                 lockIcon.setImageScale(LOCK_ICON_ACTIVE_SCALE, true, 150,
-                        mFastOutLinearInterpolator);
+                        Interpolators.FAST_OUT_LINEAR_IN);
             } else if (!active && mUnlockIconActive && mTracking) {
                 lockIcon.setImageAlpha(lockIcon.getRestingAlpha(), true /* animate */,
-                        150, mFastOutLinearInterpolator, null);
+                        150, Interpolators.FAST_OUT_LINEAR_IN, null);
                 lockIcon.setImageScale(1.0f, true, 150,
-                        mFastOutLinearInterpolator);
+                        Interpolators.FAST_OUT_LINEAR_IN);
             }
             mUnlockIconActive = active;
         }
@@ -1727,7 +1713,7 @@
         float translation = stackTranslation / HEADER_RUBBERBAND_FACTOR;
         if (mHeadsUpManager.hasPinnedHeadsUp() || mIsExpansionFromHeadsUp) {
             translation = mNotificationStackScroller.getTopPadding() + stackTranslation
-                    - mNotificationTopPadding - mQsMinExpansionHeight;
+                    - mQsMinExpansionHeight;
         }
         return Math.min(0, translation);
     }
@@ -1892,8 +1878,8 @@
         if (!expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD
                 || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) {
             KeyguardAffordanceView lockIcon = mKeyguardBottomArea.getLockIcon();
-            lockIcon.setImageAlpha(0.0f, true, 100, mFastOutLinearInterpolator, null);
-            lockIcon.setImageScale(2.0f, true, 100, mFastOutLinearInterpolator);
+            lockIcon.setImageAlpha(0.0f, true, 100, Interpolators.FAST_OUT_LINEAR_IN, null);
+            lockIcon.setImageScale(2.0f, true, 100, Interpolators.FAST_OUT_LINEAR_IN);
         }
     }
 
@@ -2033,12 +2019,12 @@
      */
     private void startHighlightIconAnimation(final KeyguardAffordanceView icon) {
         icon.setImageAlpha(1.0f, true, KeyguardAffordanceHelper.HINT_PHASE1_DURATION,
-                mFastOutSlowInInterpolator, new Runnable() {
+                Interpolators.FAST_OUT_SLOW_IN, new Runnable() {
                     @Override
                     public void run() {
                         icon.setImageAlpha(icon.getRestingAlpha(),
                                 true /* animate */, KeyguardAffordanceHelper.HINT_PHASE1_DURATION,
-                                mFastOutSlowInInterpolator, null);
+                                Interpolators.FAST_OUT_SLOW_IN, null);
                     }
                 });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index f0b7894..f036d04 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -29,7 +29,6 @@
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
 import android.view.ViewTreeObserver;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 
@@ -39,6 +38,7 @@
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
@@ -100,8 +100,6 @@
     private float mInitialTouchX;
     private boolean mTouchDisabled;
 
-    private Interpolator mLinearOutSlowInInterpolator;
-    private Interpolator mFastOutSlowInInterpolator;
     private Interpolator mBounceInterpolator;
     protected KeyguardBottomAreaView mKeyguardBottomArea;
 
@@ -161,7 +159,7 @@
         }
         mPeekAnimator = ObjectAnimator.ofFloat(this, "expandedHeight", mPeekHeight)
                 .setDuration(250);
-        mPeekAnimator.setInterpolator(mLinearOutSlowInInterpolator);
+        mPeekAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
         mPeekAnimator.addListener(new AnimatorListenerAdapter() {
             private boolean mCancelled;
 
@@ -187,10 +185,6 @@
     public PanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mFlingAnimationUtils = new FlingAnimationUtils(context, 0.6f);
-        mFastOutSlowInInterpolator =
-                AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in);
-        mLinearOutSlowInInterpolator =
-                AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
         mBounceInterpolator = new BounceInterpolator();
         mFalsingManager = FalsingManager.getInstance(context);
     }
@@ -951,7 +945,7 @@
         float target = Math.max(0, getMaxPanelHeight() - mHintDistance);
         ValueAnimator animator = createHeightAnimator(target);
         animator.setDuration(250);
-        animator.setInterpolator(mFastOutSlowInInterpolator);
+        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         animator.addListener(new AnimatorListenerAdapter() {
             private boolean mCancelled;
 
@@ -975,7 +969,7 @@
         mKeyguardBottomArea.getIndicationView().animate()
                 .translationY(-mHintDistance)
                 .setDuration(250)
-                .setInterpolator(mFastOutSlowInInterpolator)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 .withEndAction(new Runnable() {
                     @Override
                     public void run() {
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 ffc836c..f2dea3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -47,6 +47,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
 import android.inputmethodservice.InputMethodService;
 import android.media.AudioAttributes;
 import android.media.MediaMetadata;
@@ -87,14 +88,13 @@
 import android.view.ViewStub;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
-import android.view.animation.AccelerateDecelerateInterpolator;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.view.animation.PathInterpolator;
 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;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
@@ -114,6 +114,8 @@
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.recents.ScreenPinningRequest;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.DockingTopTaskEvent;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.BackDropView;
@@ -124,6 +126,7 @@
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.GestureRecorder;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationData.Entry;
@@ -131,7 +134,6 @@
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.SignalClusterView;
-import com.android.systemui.statusbar.SpeedBumpView;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
 import com.android.systemui.statusbar.policy.AccessibilityController;
@@ -141,7 +143,6 @@
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
 import com.android.systemui.statusbar.policy.CastControllerImpl;
 import com.android.systemui.statusbar.policy.FlashlightController;
-import com.android.systemui.statusbar.policy.FullscreenUserSwitcher;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.HotspotControllerImpl;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -285,7 +286,6 @@
     protected KeyguardMonitor mKeyguardMonitor;
     BrightnessMirrorController mBrightnessMirrorController;
     AccessibilityController mAccessibilityController;
-    FullscreenUserSwitcher mFullscreenUserSwitcher;
     FingerprintUnlockController mFingerprintUnlockController;
 
     int mNaturalBarHeight = -1;
@@ -440,10 +440,8 @@
     private boolean mDozingRequested;
     protected boolean mScrimSrcModeEnabled;
 
-    private Interpolator mLinearInterpolator = new LinearInterpolator();
-    private Interpolator mBackdropInterpolator = new AccelerateDecelerateInterpolator();
-    public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
-    public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
+    public static final Interpolator ALPHA_IN = Interpolators.ALPHA_IN;
+    public static final Interpolator ALPHA_OUT = Interpolators.ALPHA_OUT;
 
     private BackDropView mBackdrop;
     private ImageView mBackdropFront, mBackdropBack;
@@ -746,9 +744,7 @@
         mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
         mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
 
-        SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate(
-                        R.layout.status_bar_notification_speed_bump, mStackScroller, false);
-        mStackScroller.setSpeedBumpView(speedBump);
+
         mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
                 R.layout.status_bar_no_notifications, mStackScroller, false);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
@@ -757,7 +753,7 @@
         mDismissView.setOnButtonClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                MetricsLogger.action(mContext, MetricsLogger.ACTION_DISMISS_ALL_NOTES);
+                MetricsLogger.action(mContext, MetricsEvent.ACTION_DISMISS_ALL_NOTES);
                 clearAllNotifications();
             }
         });
@@ -854,16 +850,7 @@
         if (UserManager.get(mContext).isUserSwitcherEnabled()) {
             mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
                     mHandler, this);
-            if (mUserSwitcherController.useFullscreenUserSwitcher()) {
-                mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, mUserSwitcherController,
-                        (ViewStub) mStatusBarWindow.findViewById(
-                                R.id.fullscreen_user_switcher_stub));
-            } else {
-                // Fullscreen user switcher does not show keyguard. Hence no KeyguardUserSwitcher.
-                mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
-                        (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
-                        mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
-            }
+            createUserSwitcher();
         }
 
         // Set up the quick settings tile panel
@@ -934,6 +921,12 @@
         return mStatusBarView;
     }
 
+    protected void createUserSwitcher() {
+        mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
+                (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
+                mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
+    }
+
     protected void inflateStatusBarWindow(Context context) {
         mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
                 R.layout.super_status_bar, null);
@@ -962,14 +955,8 @@
     }
 
     protected void inflateNavigationBarView(Context context) {
-        // Optionally show app shortcuts in the nav bar "shelf" area.
-        if (shouldShowAppShelf()) {
-            mNavigationBarView = (NavigationBarView) View.inflate(
-                    context, R.layout.navigation_bar_with_apps, null);
-        } else {
-            mNavigationBarView = (NavigationBarView) View.inflate(
-                    context, R.layout.navigation_bar, null);
-        }
+        mNavigationBarView = (NavigationBarView) View.inflate(
+                context, R.layout.navigation_bar, null);
     }
 
     protected void initSignalCluster(View containerView) {
@@ -982,21 +969,6 @@
         }
     }
 
-    /** Returns true if the app shelf should be shown in the nav bar. */
-    private boolean shouldShowAppShelf() {
-        // Allow adb to override the default shelf behavior:
-        // adb shell settings put system demo_app_shelf 0  # Zero forces it off.
-        // adb shell settings put system demo_app_shelf 1  # Non-zero forces it on.
-        final int DEFAULT = -1;
-        final int shelfOverride =
-                Settings.System.getInt(mContext.getContentResolver(), "demo_app_shelf", DEFAULT);
-        if (shelfOverride != DEFAULT) {
-            return shelfOverride != 0;
-        }
-        // Otherwise default to the platform feature.
-        return FREEFORM_WINDOW_MANAGEMENT;
-    }
-
     private void clearAllNotifications() {
 
         // animate-swipe all dismissable notifications, then animate the shade closed
@@ -1134,12 +1106,24 @@
         @Override
         public boolean onLongClick(View v) {
             if (mRecents != null) {
-                boolean docked = mRecents.dockTopTask(false /* draggingInRecents */,
+                Point realSize = new Point();
+                mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY)
+                        .getRealSize(realSize);
+                Rect initialBounds;
+
+                // Hack level over 9000: Make it one pixel smaller so activity manager doesn't
+                // dismiss it immediately again. Remove once b/26777526 is fixed.
+                if (mContext.getResources().getConfiguration().orientation
+                        == Configuration.ORIENTATION_LANDSCAPE) {
+                    initialBounds = new Rect(0, 0, realSize.x - 1, realSize.y);
+                } else {
+                    initialBounds = new Rect(0, 0, realSize.x, realSize.y - 1);
+                }
+                boolean docked = mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
                         ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
-                        null /* initialBounds */);
+                        initialBounds);
                 if (docked) {
-                    MetricsLogger.action(mContext,
-                            MetricsLogger.ACTION_WINDOW_DOCK_LONGPRESS);
+                    MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS);
                     return true;
                 }
             }
@@ -1154,7 +1138,7 @@
             if (shouldDisableNavbarGestures()) {
                 return false;
             }
-            MetricsLogger.action(mContext, MetricsLogger.ACTION_ASSIST_LONG_PRESS);
+            MetricsLogger.action(mContext, MetricsEvent.ACTION_ASSIST_LONG_PRESS);
             mAssistManager.startAssist(new Bundle() /* args */);
             awakenDreams();
             if (mNavigationBarView != null) {
@@ -1282,7 +1266,7 @@
         }
 
         if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
-            if (mNotificationData.shouldSuppressScreenOn(notification.getKey())) {
+            if (shouldSupressFullScreenIntent(notification.getKey())) {
                 if (DEBUG) {
                     Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + notification.getKey());
                 }
@@ -1309,6 +1293,14 @@
         setAreThereNotifications();
     }
 
+    private boolean shouldSupressFullScreenIntent(String key) {
+        if (mPowerManager.isInteractive()) {
+            return mNotificationData.shouldSuppressPeek(key);
+        } else {
+            return mNotificationData.shouldSuppressScreenOn(key);
+        }
+    }
+
     @Override
     protected void updateNotificationRanking(RankingMap ranking) {
         mNotificationData.updateRanking(ranking);
@@ -1867,7 +1859,7 @@
                             // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in
                             // libhwui.
                             .alpha(0.002f)
-                            .setInterpolator(mBackdropInterpolator)
+                            .setInterpolator(Interpolators.ACCELERATE_DECELERATE)
                             .setDuration(300)
                             .setStartDelay(0)
                             .withEndAction(new Runnable() {
@@ -1886,7 +1878,7 @@
                                 // behind.
                                 .setDuration(mKeyguardFadingAwayDuration / 2)
                                 .setStartDelay(mKeyguardFadingAwayDelay)
-                                .setInterpolator(mLinearInterpolator)
+                                .setInterpolator(Interpolators.LINEAR)
                                 .start();
                     }
                 }
@@ -3114,9 +3106,6 @@
         setControllerUsers();
         clearCurrentMediaNotification();
         updateMediaMetaData(true);
-        if (mFullscreenUserSwitcher != null) {
-            mFullscreenUserSwitcher.onUserSwitched(newUserId);
-        }
     }
 
     private void setControllerUsers() {
@@ -3741,7 +3730,7 @@
                         .isSecure(mCurrentUserId));
     }
 
-    private void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
+    protected void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
         if (mState == StatusBarState.KEYGUARD) {
             mKeyguardIndicationController.setVisible(true);
             mNotificationPanel.resetViews();
@@ -3765,17 +3754,11 @@
             mScrimController.setKeyguardShowing(false);
             mIconPolicy.setKeyguardShowing(false);
         }
-        if (mFullscreenUserSwitcher != null) {
-            if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
-                mFullscreenUserSwitcher.show();
-            } else {
-                mFullscreenUserSwitcher.hide();
-            }
-        }
+
         mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
         updateDozingState();
         updatePublicMode();
-        updateStackScrollerState(goingToFullShade);
+        updateStackScrollerState(goingToFullShade, fromShadeLocked);
         updateNotifications();
         checkBarModes();
         updateMediaMetaData(false);
@@ -3796,11 +3779,11 @@
                         != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate);
     }
 
-    public void updateStackScrollerState(boolean goingToFullShade) {
+    public void updateStackScrollerState(boolean goingToFullShade, boolean fromShadeLocked) {
         if (mStackScroller == null) return;
         boolean onKeyguard = mState == StatusBarState.KEYGUARD;
         mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
-        mStackScroller.setDimmed(onKeyguard, false /* animate */);
+        mStackScroller.setDimmed(onKeyguard, fromShadeLocked /* animate */);
         mStackScroller.setExpandingEnabled(!onKeyguard);
         ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
         mStackScroller.setActivatedChild(null);
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 7e27856..9c2159be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -38,6 +38,7 @@
 import com.android.systemui.qs.tiles.CastTile;
 import com.android.systemui.qs.tiles.CellularTile;
 import com.android.systemui.qs.tiles.ColorInversionTile;
+import com.android.systemui.qs.tiles.DataSaverTile;
 import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.qs.tiles.FlashlightTile;
 import com.android.systemui.qs.tiles.HotspotTile;
@@ -346,6 +347,7 @@
         else if (tileSpec.equals("hotspot")) return new HotspotTile(this);
         else if (tileSpec.equals("user")) return new UserTile(this);
         else if (tileSpec.equals("battery")) return new BatteryTile(this);
+        else if (tileSpec.equals("saver")) return new DataSaverTile(this);
         else if (tileSpec.equals(ColorMatrixTile.COLOR_MATRIX_SPEC))
             return new ColorMatrixTile(this);
         // Intent tiles.
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 5b44f0a..f18c341 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 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;
@@ -70,6 +71,8 @@
     private QuickQSPanel mHeaderQsPanel;
     private boolean mShowEmergencyCallsOnly;
     private float mDateTimeTranslation;
+    private MultiUserSwitch mMultiUserSwitch;
+    private ImageView mMultiUserAvatar;
 
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -100,6 +103,9 @@
         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);
+
         // RenderThread is doing more harm than good when touching the header (to expand quick
         // settings), so disable it for this view
         ((RippleDrawable) getBackground()).setForceSoftware(true);
@@ -173,6 +179,12 @@
                 ? View.VISIBLE : View.INVISIBLE);
         mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
                 TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
+        mMultiUserSwitch.setVisibility(mMultiUserSwitch.hasMultipleUsers() ? View.VISIBLE
+                : View.GONE);
+    }
+
+    private boolean hasMultiUsers() {
+        return false;
     }
 
     private void updateListeners() {
@@ -194,6 +206,7 @@
         setupHost(qsPanel.getHost());
         if (mQsPanel != null) {
             mQsPanel.setCallback(mQsPanelCallback);
+            mMultiUserSwitch.setQsPanel(qsPanel);
         }
     }
 
@@ -254,7 +267,12 @@
 
     @Override
     public void setUserInfoController(UserInfoController userInfoController) {
-        // Don't care.
+        userInfoController.addListener(new UserInfoController.OnUserInfoChangedListener() {
+            @Override
+            public void onUserInfoChanged(String name, Drawable picture) {
+                mMultiUserAvatar.setImageDrawable(picture);
+            }
+        });
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 403199a..f310c2c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -22,6 +22,7 @@
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.view.animation.DecelerateInterpolator;
@@ -497,4 +498,16 @@
     public void dontAnimateBouncerChangesUntilNextFrame() {
         mDontAnimateBouncerChanges = true;
     }
+
+    public void setExcludedBackgroundArea(Rect area) {
+        mScrimBehind.setExcludedArea(area);
+    }
+
+    public int getScrimBehindColor() {
+        return mScrimBehind.getScrimColorWithAlpha();
+    }
+
+    public void setScrimBehindChangeRunnable(Runnable changeRunnable) {
+        mScrimBehind.setChangeRunnable(changeRunnable);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
index 512af1b..7247b57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
@@ -26,7 +26,9 @@
 import android.view.ViewConfiguration;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
+
 import com.android.keyguard.AlphaOptimizedImageButton;
+import com.android.systemui.statusbar.Interpolators;
 
 public class SettingsButton extends AlphaOptimizedImageButton {
 
@@ -157,8 +159,7 @@
         performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
         mUpToSpeed = true;
         mAnimator = ObjectAnimator.ofFloat(this, View.ROTATION, 0, 360);
-        mAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.linear));
+        mAnimator.setInterpolator(Interpolators.LINEAR);
         mAnimator.setDuration(FULL_SPEED_LENGTH);
         mAnimator.setRepeatCount(Animation.INFINITE);
         mAnimator.start();
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 64fb066..c6537e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -32,15 +32,15 @@
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
+
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarIconView;
@@ -63,8 +63,6 @@
 
     private Context mContext;
     private PhoneStatusBar mPhoneStatusBar;
-    private Interpolator mLinearOutSlowIn;
-    private Interpolator mFastOutSlowIn;
     private DemoStatusIcons mDemoStatusIcons;
 
     private LinearLayout mSystemIconArea;
@@ -129,10 +127,6 @@
         maybeScaleBatteryMeterView(context);
 
         mClock = (TextView) statusBar.findViewById(R.id.clock);
-        mLinearOutSlowIn = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.linear_out_slow_in);
-        mFastOutSlowIn = AnimationUtils.loadInterpolator(mContext,
-                android.R.interpolator.fast_out_slow_in);
         mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone);
         mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone);
         mHandler = new Handler();
@@ -348,7 +342,7 @@
                 .alpha(0f)
                 .setDuration(160)
                 .setStartDelay(0)
-                .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                .setInterpolator(Interpolators.ALPHA_OUT)
                 .withEndAction(new Runnable() {
                     @Override
                     public void run() {
@@ -370,7 +364,7 @@
         v.animate()
                 .alpha(1f)
                 .setDuration(320)
-                .setInterpolator(PhoneStatusBar.ALPHA_IN)
+                .setInterpolator(Interpolators.ALPHA_IN)
                 .setStartDelay(50)
 
                 // We need to clean up any pending end action from animateHide if we call
@@ -382,7 +376,7 @@
         if (mPhoneStatusBar.isKeyguardFadingAway()) {
             v.animate()
                     .setDuration(mPhoneStatusBar.getKeyguardFadingAwayDuration())
-                    .setInterpolator(mLinearOutSlowIn)
+                    .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
                     .setStartDelay(mPhoneStatusBar.getKeyguardFadingAwayDelay())
                     .start();
         }
@@ -419,7 +413,7 @@
         });
         mTintAnimator.setDuration(duration);
         mTintAnimator.setStartDelay(delay);
-        mTintAnimator.setInterpolator(mFastOutSlowIn);
+        mTintAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         mTintAnimator.start();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
index 56c1e10..1aae496 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import com.android.systemui.R;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
@@ -31,10 +29,11 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 
+import com.android.systemui.R;
+import com.android.systemui.statusbar.Interpolators;
+
 public class TrustDrawable extends Drawable {
 
     private static final long ENTERING_FROM_UNSET_START_DELAY = 200;
@@ -69,10 +68,6 @@
 
     private final Animator mVisibleAnimator;
 
-    private final Interpolator mLinearOutSlowInInterpolator;
-    private final Interpolator mFastOutSlowInInterpolator;
-    private final Interpolator mAccelerateDecelerateInterpolator;
-
     public TrustDrawable(Context context) {
         Resources r = context.getResources();
         mInnerRadiusVisibleMin = r.getDimension(R.dimen.trust_circle_inner_radius_visible_min);
@@ -83,12 +78,6 @@
 
         mCurInnerRadius = mInnerRadiusEnter;
 
-        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(
-                context, android.R.interpolator.linear_out_slow_in);
-        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(
-                context, android.R.interpolator.fast_out_slow_in);
-        mAccelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator();
-
         mVisibleAnimator = makeVisibleAnimator();
 
         mPaint = new Paint();
@@ -212,19 +201,19 @@
     private Animator makeVisibleAnimator() {
         return makeAnimators(mInnerRadiusVisibleMax, mInnerRadiusVisibleMin,
                 ALPHA_VISIBLE_MAX, ALPHA_VISIBLE_MIN, VISIBLE_DURATION,
-                mAccelerateDecelerateInterpolator,
+                Interpolators.ACCELERATE_DECELERATE,
                 true /* repeating */, false /* stateUpdateListener */);
     }
 
     private Animator makeEnterAnimator(float radius, int alpha) {
         return makeAnimators(radius, mInnerRadiusVisibleMax,
-                alpha, ALPHA_VISIBLE_MAX, ENTER_DURATION, mLinearOutSlowInInterpolator,
+                alpha, ALPHA_VISIBLE_MAX, ENTER_DURATION, Interpolators.LINEAR_OUT_SLOW_IN,
                 false /* repeating */, true /* stateUpdateListener */);
     }
 
     private Animator makeExitAnimator(float radius, int alpha) {
         return makeAnimators(radius, mInnerRadiusExit,
-                alpha, 0, EXIT_DURATION, mFastOutSlowInInterpolator,
+                alpha, 0, EXIT_DURATION, Interpolators.FAST_OUT_SLOW_IN,
                 false /* repeating */, true /* stateUpdateListener */);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 4ae0321..59d54ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -16,15 +16,15 @@
 
 package com.android.systemui.statusbar.policy;
 
-import com.android.systemui.R;
-import com.android.systemui.statusbar.ScrimView;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
-
 import android.view.View;
 import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 
+import com.android.systemui.R;
+import com.android.systemui.statusbar.Interpolators;
+import com.android.systemui.statusbar.ScrimView;
+import com.android.systemui.statusbar.phone.StatusBarWindowView;
+
 /**
  * Controls showing and hiding of the brightness mirror.
  */
@@ -46,13 +46,13 @@
 
     public void showMirror() {
         mBrightnessMirror.setVisibility(View.VISIBLE);
-        mScrimBehind.animateViewAlpha(0.0f, TRANSITION_DURATION_OUT, PhoneStatusBar.ALPHA_OUT);
+        mScrimBehind.animateViewAlpha(0.0f, TRANSITION_DURATION_OUT, Interpolators.ALPHA_OUT);
         outAnimation(mNotificationPanel.animate())
                 .withLayer();
     }
 
     public void hideMirror() {
-        mScrimBehind.animateViewAlpha(1.0f, TRANSITION_DURATION_IN, PhoneStatusBar.ALPHA_IN);
+        mScrimBehind.animateViewAlpha(1.0f, TRANSITION_DURATION_IN, Interpolators.ALPHA_IN);
         inAnimation(mNotificationPanel.animate())
                 .withLayer()
                 .withEndAction(new Runnable() {
@@ -66,12 +66,12 @@
     private ViewPropertyAnimator outAnimation(ViewPropertyAnimator a) {
         return a.alpha(0.0f)
                 .setDuration(TRANSITION_DURATION_OUT)
-                .setInterpolator(PhoneStatusBar.ALPHA_OUT);
+                .setInterpolator(Interpolators.ALPHA_OUT);
     }
     private ViewPropertyAnimator inAnimation(ViewPropertyAnimator a) {
         return a.alpha(1.0f)
                 .setDuration(TRANSITION_DURATION_IN)
-                .setInterpolator(PhoneStatusBar.ALPHA_IN);
+                .setInterpolator(Interpolators.ALPHA_IN);
     }
 
 
@@ -103,10 +103,5 @@
         lp.gravity = mBrightnessMirror.getResources().getInteger(
                 R.integer.notification_panel_layout_gravity);
         mBrightnessMirror.setLayoutParams(lp);
-
-        int padding = mBrightnessMirror.getResources().getDimensionPixelSize(
-                R.dimen.notification_side_padding);
-        mBrightnessMirror.setPadding(padding, mBrightnessMirror.getPaddingTop(),
-                padding, mBrightnessMirror.getPaddingBottom());
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverController.java
new file mode 100644
index 0000000..186e8b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverController.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT 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.policy;
+
+import android.content.Context;
+import android.net.INetworkPolicyListener;
+import android.net.NetworkPolicyManager;
+import android.os.Handler;
+import android.os.RemoteException;
+
+import java.util.ArrayList;
+
+public class DataSaverController {
+
+    private final Handler mHandler = new Handler();
+    private final ArrayList<Listener> mListeners = new ArrayList<>();
+    private final NetworkPolicyManager mPolicyManager;
+
+    public DataSaverController(Context context) {
+        mPolicyManager = NetworkPolicyManager.from(context);
+    }
+
+    private void handleRestrictBackgroundChanged(boolean isDataSaving) {
+        final int N = mListeners.size();
+        for (int i = 0; i < N; i++) {
+            mListeners.get(i).onDataSaverChanged(isDataSaving);
+        }
+    }
+
+    public void addListener(Listener listener) {
+        mListeners.add(listener);
+        if (mListeners.size() == 1) {
+            mPolicyManager.registerListener(mPolicyListener);
+        }
+        listener.onDataSaverChanged(isDataSaverEnabled());
+    }
+
+    public void remListener(Listener listener) {
+        mListeners.remove(listener);
+        if (mListeners.size() == 0) {
+            mPolicyManager.unregisterListener(mPolicyListener);
+        }
+    }
+
+    public boolean isDataSaverEnabled() {
+        return mPolicyManager.getRestrictBackground();
+    }
+
+    public void setDataSaverEnabled(boolean enabled) {
+        mPolicyManager.setRestrictBackground(enabled);
+    }
+
+    private final INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
+        @Override
+        public void onUidRulesChanged(int i, int i1) throws RemoteException {
+        }
+
+        @Override
+        public void onMeteredIfacesChanged(String[] strings) throws RemoteException {
+        }
+
+        @Override
+        public void onRestrictBackgroundChanged(final boolean isDataSaving) throws RemoteException {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    handleRestrictBackgroundChanged(isDataSaving);
+                }
+            });
+        }
+    };
+
+    public interface Listener {
+        void onDataSaverChanged(boolean isDataSaving);
+    }
+
+}
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 dd7bd56..f065522 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -84,7 +84,6 @@
 
     private final View mStatusBarWindowView;
     private final int mStatusBarHeight;
-    private final int mNotificationsTopPadding;
     private final Context mContext;
     private final NotificationGroupManager mGroupManager;
     private PhoneStatusBar mBar;
@@ -138,8 +137,6 @@
         mGroupManager = groupManager;
         mStatusBarHeight = resources.getDimensionPixelSize(
                 com.android.internal.R.dimen.status_bar_height);
-        mNotificationsTopPadding = context.getResources()
-                .getDimensionPixelSize(R.dimen.notifications_top_padding);
     }
 
     private void updateTouchableRegionListener() {
@@ -399,7 +396,7 @@
             }
 
             info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
-            info.touchableRegion.set(minX, 0, maxX, maxY + mNotificationsTopPadding);
+            info.touchableRegion.set(minX, 0, maxX, maxY);
         } else if (mHeadsUpGoingAway || mWaitingOnCollapseWhenGoingAway) {
             info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
             info.touchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index 41aeac9..5719f76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -20,8 +20,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
-import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.settingslib.TetherUtil;
@@ -34,21 +34,18 @@
 
     private static final String TAG = "HotspotController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final Intent TETHER_SERVICE_INTENT = new Intent()
-            .putExtra(TetherUtil.EXTRA_ADD_TETHER_TYPE, TetherUtil.TETHERING_WIFI)
-            .putExtra(TetherUtil.EXTRA_SET_ALARM, true)
-            .putExtra(TetherUtil.EXTRA_RUN_PROVISION, true)
-            .putExtra(TetherUtil.EXTRA_ENABLE_WIFI_TETHER, true)
-            .setComponent(TetherUtil.TETHER_SERVICE);
 
     private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
     private final Receiver mReceiver = new Receiver();
+    private final ConnectivityManager mConnectivityManager;
     private final Context mContext;
 
     private int mHotspotState;
 
     public HotspotControllerImpl(Context context) {
         mContext = context;
+        mConnectivityManager = (ConnectivityManager)context.getSystemService(
+                Context.CONNECTIVITY_SERVICE);
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -72,6 +69,7 @@
         return null;
     }
 
+    @Override
     public void addCallback(Callback callback) {
         if (callback == null || mCallbacks.contains(callback)) return;
         if (DEBUG) Log.d(TAG, "addCallback " + callback);
@@ -79,6 +77,7 @@
         mReceiver.setListening(!mCallbacks.isEmpty());
     }
 
+    @Override
     public void removeCallback(Callback callback) {
         if (callback == null) return;
         if (DEBUG) Log.d(TAG, "removeCallback " + callback);
@@ -96,13 +95,24 @@
         return TetherUtil.isTetheringSupported(mContext);
     }
 
+    static final class OnStartTetheringCallback extends
+            ConnectivityManager.OnStartTetheringCallback {
+        @Override
+        public void onTetheringStarted() {}
+        @Override
+        public void onTetheringFailed() {
+          // TODO: Show error.
+        }
+    }
+
     @Override
     public void setHotspotEnabled(boolean enabled) {
-        // Call provisioning app which is called when enabling Tethering from Settings
-        if (enabled && TetherUtil.isProvisioningNeeded(mContext)) {
-            mContext.startServiceAsUser(TETHER_SERVICE_INTENT, UserHandle.CURRENT);
+        if (enabled) {
+            OnStartTetheringCallback callback = new OnStartTetheringCallback();
+            mConnectivityManager.startTethering(
+                    ConnectivityManager.TETHERING_WIFI, false, callback);
         } else {
-            TetherUtil.setWifiTethering(enabled, mContext);
+            mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
index 3f63b5f..d739d6c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
@@ -32,7 +32,7 @@
 import android.view.animation.Interpolator;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.Interpolators;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -59,7 +59,6 @@
     private int mMaxWidth;
 
     private final Interpolator mInterpolator = new LogInterpolator();
-    private final Interpolator mAlphaExitInterpolator = PhoneStatusBar.ALPHA_OUT;
     private boolean mSupportHardware;
     private final View mTargetView;
 
@@ -225,7 +224,7 @@
 
     private void exitSoftware() {
         ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(this, "glowAlpha", mGlowAlpha, 0f);
-        alphaAnimator.setInterpolator(mAlphaExitInterpolator);
+        alphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
         alphaAnimator.setDuration(ANIMATION_DURATION_FADE);
         alphaAnimator.addListener(mAnimatorListener);
         alphaAnimator.start();
@@ -331,7 +330,7 @@
         final RenderNodeAnimator opacityAnim = new RenderNodeAnimator(mPaintProp,
                 RenderNodeAnimator.PAINT_ALPHA, 0);
         opacityAnim.setDuration(ANIMATION_DURATION_FADE);
-        opacityAnim.setInterpolator(mAlphaExitInterpolator);
+        opacityAnim.setInterpolator(Interpolators.ALPHA_OUT);
         opacityAnim.addListener(mAnimatorListener);
         opacityAnim.setTarget(mTargetView);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index 5cf6156..0959b0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -21,6 +21,7 @@
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.database.DataSetObserver;
+import android.graphics.Interpolator;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -33,9 +34,9 @@
 import com.android.settingslib.animation.AppearAnimationUtils;
 import com.android.systemui.R;
 import com.android.systemui.qs.tiles.UserDetailItemView;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 /**
  * Manages the user switcher on the Keyguard.
@@ -73,8 +74,7 @@
             mAdapter.registerDataSetObserver(mDataSetObserver);
             mUserSwitcherController = userSwitcherController;
             mAppearAnimationUtils = new AppearAnimationUtils(context, 400, -0.5f, 0.5f,
-                    AnimationUtils.loadInterpolator(
-                            context, android.R.interpolator.fast_out_slow_in));
+                    Interpolators.FAST_OUT_SLOW_IN);
             mUserSwitcherContainer.setKeyguardUserSwitcher(this);
         } else {
             mUserSwitcherContainer = null;
@@ -158,7 +158,7 @@
         mAnimating = true;
         mBgAnimator = ObjectAnimator.ofInt(mBackground, "alpha", 0, 255);
         mBgAnimator.setDuration(400);
-        mBgAnimator.setInterpolator(PhoneStatusBar.ALPHA_IN);
+        mBgAnimator.setInterpolator(Interpolators.ALPHA_IN);
         mBgAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -174,7 +174,7 @@
         mUserSwitcher.animate()
                 .alpha(0f)
                 .setDuration(300)
-                .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                .setInterpolator(Interpolators.ALPHA_OUT)
                 .withEndAction(new Runnable() {
                     @Override
                     public void run() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index ad8e3bd..8fd4d9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -206,7 +206,8 @@
 
         // Show icon in QS when we are connected or need to show roaming.
         boolean showDataIcon = mCurrentState.dataConnected
-                || mCurrentState.iconGroup == TelephonyIcons.ROAMING;
+                || mCurrentState.iconGroup == TelephonyIcons.ROAMING
+                || mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED;
         IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
                 getCurrentIconId(), contentDescription);
 
@@ -227,7 +228,8 @@
                         && !mCurrentState.carrierNetworkChangeMode
                         && mCurrentState.activityOut;
         showDataIcon &= mCurrentState.isDefault
-                || mCurrentState.iconGroup == TelephonyIcons.ROAMING;
+                || mCurrentState.iconGroup == TelephonyIcons.ROAMING
+                || mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED;
         int typeIcon = showDataIcon ? icons.mDataType : 0;
         mCallbackHandler.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
                 activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
@@ -385,6 +387,8 @@
             mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
         } else if (isRoaming()) {
             mCurrentState.iconGroup = TelephonyIcons.ROAMING;
+        } else if (isDataDisabled()) {
+            mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED;
         }
         if (isEmergencyOnly() != mCurrentState.isEmergency) {
             mCurrentState.isEmergency = isEmergencyOnly();
@@ -399,6 +403,10 @@
         notifyListenersIfNecessary();
     }
 
+    private boolean isDataDisabled() {
+        return !mPhone.getDataEnabled(mSubscriptionInfo.getSubscriptionId());
+    }
+
     @VisibleForTesting
     void setActivity(int activity) {
         mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index b2bcde3..755a5b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -33,6 +33,7 @@
     void onUserSwitched(int newUserId);
     AccessPointController getAccessPointController();
     DataUsageController getMobileDataController();
+    DataSaverController getDataSaverController();
 
     public interface SignalCallback {
         void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 3385c82..107a904 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -78,6 +78,7 @@
     private final SubscriptionManager mSubscriptionManager;
     private final boolean mHasMobileDataFeature;
     private final SubscriptionDefaults mSubDefaults;
+    private final DataSaverController mDataSaverController;
     private Config mConfig;
 
     // Subcontrollers.
@@ -156,6 +157,7 @@
         mConfig = config;
         mReceiverHandler = new Handler(bgLooper);
         mCallbackHandler = callbackHandler;
+        mDataSaverController = new DataSaverController(context);
 
         mSubscriptionManager = subManager;
         mSubDefaults = defaultsHandler;
@@ -189,6 +191,10 @@
         updateAirplaneMode(true /* force callback */);
     }
 
+    public DataSaverController getDataSaverController() {
+        return mDataSaverController;
+    }
+
     private void registerListeners() {
         for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
             mobileSignalController.registerListener();
@@ -811,11 +817,11 @@
 
     public static class SubscriptionDefaults {
         public int getDefaultVoiceSubId() {
-            return SubscriptionManager.getDefaultVoiceSubId();
+            return SubscriptionManager.getDefaultVoiceSubscriptionId();
         }
 
         public int getDefaultDataSubId() {
-            return SubscriptionManager.getDefaultDataSubId();
+            return SubscriptionManager.getDefaultDataSubscriptionId();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index 83e0446..6ff8f77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -208,6 +208,8 @@
     static final int ICON_CARRIER_NETWORK_CHANGE =
             R.drawable.stat_sys_signal_carrier_network_change_animation;
 
+    static final int ICON_DATA_DISABLED = R.drawable.stat_sys_data_disabled;
+
     static final int QS_ICON_LTE = R.drawable.ic_qs_signal_lte;
     static final int QS_ICON_3G = R.drawable.ic_qs_signal_3g;
     static final int QS_ICON_4G = R.drawable.ic_qs_signal_4g;
@@ -215,6 +217,8 @@
     static final int QS_ICON_CARRIER_NETWORK_CHANGE =
             R.drawable.ic_qs_signal_carrier_network_change_animation;
 
+    static final int QS_ICON_DATA_DISABLED = R.drawable.ic_qs_data_disabled;
+
     static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup(
             "CARRIER_NETWORK_CHANGE",
             TelephonyIcons.TELEPHONY_CARRIER_NETWORK_CHANGE,
@@ -373,5 +377,20 @@
             false,
             TelephonyIcons.QS_DATA_R
             );
+
+    static final MobileIconGroup DATA_DISABLED = new MobileIconGroup(
+            "DataDisabled",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_cell_data_off,
+            TelephonyIcons.ICON_DATA_DISABLED,
+            false,
+            TelephonyIcons.QS_ICON_DATA_DISABLED
+            );
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 05d9626..e4ded67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -49,7 +49,7 @@
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
 
-import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.internal.util.UserIcons;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.systemui.BitmapHelper;
@@ -724,7 +724,7 @@
 
         @Override
         public int getMetricsCategory() {
-            return MetricsLogger.QS_USERDETAIL;
+            return MetricsEvent.QS_USERDETAIL;
         }
     };
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index 56f6564..561b18a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -25,12 +25,12 @@
     boolean animateAlpha;
     boolean animateY;
     boolean animateZ;
-    boolean animateScale;
     boolean animateHeight;
     boolean animateTopInset;
     boolean animateDimmed;
     boolean animateDark;
     boolean animateHideSensitive;
+    public boolean animateShadowAlpha;
     boolean hasDelays;
     boolean hasGoToFullShadeEvent;
     boolean hasDarkEvent;
@@ -57,11 +57,6 @@
         return this;
     }
 
-    public AnimationFilter animateScale() {
-        animateScale = true;
-        return this;
-    }
-
     public AnimationFilter animateHeight() {
         animateHeight = true;
         return this;
@@ -87,6 +82,11 @@
         return this;
     }
 
+    public AnimationFilter animateShadowAlpha() {
+        animateShadowAlpha = true;
+        return this;
+    }
+
     /**
      * Combines multiple filters into {@code this} filter, using or as the operand .
      *
@@ -118,12 +118,12 @@
         animateAlpha |= filter.animateAlpha;
         animateY |= filter.animateY;
         animateZ |= filter.animateZ;
-        animateScale |= filter.animateScale;
         animateHeight |= filter.animateHeight;
         animateTopInset |= filter.animateTopInset;
         animateDimmed |= filter.animateDimmed;
         animateDark |= filter.animateDark;
         animateHideSensitive |= filter.animateHideSensitive;
+        animateShadowAlpha |= filter.animateShadowAlpha;
         hasDelays |= filter.hasDelays;
     }
 
@@ -131,8 +131,8 @@
         animateAlpha = false;
         animateY = false;
         animateZ = false;
-        animateScale = false;
         animateHeight = false;
+        animateShadowAlpha = false;
         animateTopInset = false;
         animateDimmed = false;
         animateDark = false;
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 dc40fb0..409dac1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -76,8 +76,8 @@
         super(context, attrs, defStyleAttr, defStyleRes);
         mChildPadding = getResources().getDimensionPixelSize(
                 R.dimen.notification_children_padding);
-        mDividerHeight = getResources().getDimensionPixelSize(
-                R.dimen.notification_children_divider_height);
+        mDividerHeight = Math.max(1, getResources().getDimensionPixelSize(
+                R.dimen.notification_divider_height));
         mMaxNotificationHeight = getResources().getDimensionPixelSize(
                 R.dimen.notification_max_height);
         mNotificationAppearDistance = getResources().getDimensionPixelSize(
@@ -324,7 +324,6 @@
             childState.dark = parentState.dark;
             childState.hideSensitive = parentState.hideSensitive;
             childState.belowSpeedBump = parentState.belowSpeedBump;
-            childState.scale =  1.0f;
             childState.clipTopAmount = 0;
             childState.topOverLap = 0;
             boolean visible = i <= lastVisibleIndex;
@@ -384,30 +383,8 @@
      * @param state the new state we animate to
      */
     public void prepareExpansionChanged(StackScrollState state) {
-        if (true) {
-            // TODO: do something that makes sense
-            return;
-        }
-        int childCount = mChildren.size();
-        StackViewState sourceState = new StackViewState();
-        ViewState dividerState = new ViewState();
-        for (int i = 0; i < childCount; i++) {
-            ExpandableNotificationRow child = mChildren.get(i);
-            StackViewState viewState = state.getViewStateForView(child);
-            sourceState.copyFrom(viewState);
-            sourceState.alpha = 0;
-            sourceState.yTranslation += mNotificationAppearDistance;
-            state.applyState(child, sourceState);
-
-            // layout the divider
-            View divider = mDividers.get(i);
-            dividerState.initFrom(divider);
-            dividerState.yTranslation = viewState.yTranslation - mDividerHeight
-                    + mNotificationAppearDistance;
-            dividerState.alpha = 0;
-            state.applyViewState(divider, dividerState);
-
-        }
+        // TODO: do something that makes sense, like placing the invisible views correctly
+        return;
     }
 
     public void startAnimationToState(StackScrollState state, StackStateAnimator stateAnimator,
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 36b2810..d5b57ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -16,12 +16,22 @@
 
 package com.android.systemui.statusbar.stack;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.TimeAnimator;
+import android.animation.ValueAnimator;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.PointF;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pair;
@@ -32,6 +42,7 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
 import android.widget.OverScroller;
 
 import com.android.systemui.ExpandHelper;
@@ -43,9 +54,8 @@
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
-import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.NotificationOverflowContainer;
-import com.android.systemui.statusbar.SpeedBumpView;
 import com.android.systemui.statusbar.StackScrollerDecorView;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -64,6 +74,7 @@
         implements SwipeHelper.Callback, ExpandHelper.Callback, ScrollAdapter,
         ExpandableView.OnHeightChangedListener, NotificationGroupManager.OnGroupChangeListener {
 
+    public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
     private static final String TAG = "NotificationStackScrollLayout";
     private static final boolean DEBUG = false;
     private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
@@ -79,6 +90,7 @@
     private SwipeHelper mSwipeHelper;
     private boolean mSwipingInProgress;
     private int mCurrentStackHeight = Integer.MAX_VALUE;
+    private final Paint mBackgroundPaint = new Paint();
 
     /**
      * mCurrentStackHeight is the actual stack height, mLastSetStackHeight is the stack height set
@@ -103,15 +115,13 @@
     private float mInitialTouchX;
     private float mInitialTouchY;
 
-    private int mSidePaddings;
     private Paint mDebugPaint;
     private int mContentHeight;
     private int mCollapsedSize;
     private int mBottomStackSlowDownHeight;
     private int mBottomStackPeekSize;
     private int mPaddingBetweenElements;
-    private int mPaddingBetweenElementsDimmed;
-    private int mPaddingBetweenElementsNormal;
+    private int mIncreasedPaddingBetweenElements;
     private int mTopPadding;
     private int mCollapseSecondCardPadding;
 
@@ -163,7 +173,6 @@
     private boolean mGoToFullShadeNeedsAnimation;
     private boolean mIsExpanded = true;
     private boolean mChildrenUpdateRequested;
-    private SpeedBumpView mSpeedBumpView;
     private boolean mIsExpansionChanging;
     private boolean mPanelTracking;
     private boolean mExpandingNotification;
@@ -183,7 +192,6 @@
      */
     private float mMinTopOverScrollToEscape;
     private int mIntrinsicPadding;
-    private int mNotificationTopPadding;
     private float mStackTranslation;
     private float mTopPaddingOverflow;
     private boolean mDontReportNextOverScroll;
@@ -234,6 +242,45 @@
     private NotificationOverflowContainer mOverflowContainer;
     private final ArrayList<Pair<ExpandableNotificationRow, Boolean>> mTmpList = new ArrayList<>();
     private FalsingManager mFalsingManager;
+    private boolean mAnimationRunning;
+    private ViewTreeObserver.OnPreDrawListener mBackgroundUpdater
+            = new ViewTreeObserver.OnPreDrawListener() {
+        @Override
+        public boolean onPreDraw() {
+            // if it needs animation
+            if (!mNeedsAnimation && !mChildrenUpdateRequested) {
+                updateBackground();
+            }
+            return true;
+        }
+    };
+    private Rect mBackgroundBounds = new Rect();
+    private Rect mStartAnimationRect = new Rect();
+    private Rect mEndAnimationRect = new Rect();
+    private Rect mCurrentBounds = new Rect(-1, -1, -1, -1);
+    private boolean mAnimateNextBackgroundBottom;
+    private boolean mAnimateNextBackgroundTop;
+    private ObjectAnimator mBottomAnimator = null;
+    private ObjectAnimator mTopAnimator = null;
+    private ActivatableNotificationView mFirstVisibleBackgroundChild = null;
+    private ActivatableNotificationView mLastVisibleBackgroundChild = null;
+    private int mBgColor;
+    private float mDimAmount;
+    private ValueAnimator mDimAnimator;
+    private Animator.AnimatorListener mDimEndListener = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mDimAnimator = null;
+        }
+    };
+    private ValueAnimator.AnimatorUpdateListener mDimUpdateListener
+            = new ValueAnimator.AnimatorUpdateListener() {
+
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            setDimAmount((Float) animation.getAnimatedValue());
+        }
+    };
 
     public NotificationStackScrollLayout(Context context) {
         this(context, null);
@@ -250,6 +297,7 @@
     public NotificationStackScrollLayout(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        mBgColor = context.getColor(R.color.notification_shade_background_color);
         int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
         int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
         mExpandHelper = new ExpandHelper(getContext(), this,
@@ -261,18 +309,20 @@
         mSwipeHelper.setLongPressListener(mLongPressListener);
         mStackScrollAlgorithm = new StackScrollAlgorithm(context);
         initView(context);
+        setWillNotDraw(false);
         if (DEBUG) {
-            setWillNotDraw(false);
             mDebugPaint = new Paint();
             mDebugPaint.setColor(0xffff0000);
             mDebugPaint.setStrokeWidth(2);
             mDebugPaint.setStyle(Paint.Style.STROKE);
         }
         mFalsingManager = FalsingManager.getInstance(context);
+        mBackgroundPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
     }
 
     @Override
     protected void onDraw(Canvas canvas) {
+        canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom, mBackgroundPaint);
         if (DEBUG) {
             int y = mTopPadding;
             canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
@@ -288,6 +338,20 @@
         }
     }
 
+    private void updateBackgroundDimming() {
+        float alpha = BACKGROUND_ALPHA_DIMMED + (1 - BACKGROUND_ALPHA_DIMMED) * (1.0f - mDimAmount);
+        // We need to manually blend in the background color
+        int scrimColor = mScrimController.getScrimBehindColor();
+        // SRC_OVER blending Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc
+        float alphaInv = 1 - alpha;
+        int color = Color.argb((int) (alpha * 255 + alphaInv * Color.alpha(scrimColor)),
+                (int) (Color.red(mBgColor) + alphaInv * Color.red(scrimColor)),
+                (int) (Color.green(mBgColor) + alphaInv * Color.green(scrimColor)),
+                (int) (Color.blue(mBgColor) + alphaInv * Color.blue(scrimColor)));
+        mBackgroundPaint.setColor(color);
+        invalidate();
+    }
+
     private void initView(Context context) {
         mScroller = new OverScroller(getContext());
         setFocusable(true);
@@ -298,36 +362,23 @@
         mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
         mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
         mOverflingDistance = configuration.getScaledOverflingDistance();
-
-        mSidePaddings = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_side_padding);
         mCollapsedSize = context.getResources()
                 .getDimensionPixelSize(R.dimen.notification_min_height);
         mBottomStackPeekSize = context.getResources()
                 .getDimensionPixelSize(R.dimen.bottom_stack_peek_amount);
         mStackScrollAlgorithm.initView(context);
-        mPaddingBetweenElementsDimmed = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_padding_dimmed);
-        mPaddingBetweenElementsNormal = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_padding);
-        updatePadding(mAmbientState.isDimmed());
+        mPaddingBetweenElements = Math.max(1, context.getResources()
+                .getDimensionPixelSize(R.dimen.notification_divider_height));
+        mIncreasedPaddingBetweenElements = context.getResources()
+                .getDimensionPixelSize(R.dimen.notification_divider_height_increased);
+
+        mBottomStackSlowDownHeight = mStackScrollAlgorithm.getBottomStackSlowDownLength();
         mMinTopOverScrollToEscape = getResources().getDimensionPixelSize(
                 R.dimen.min_top_overscroll_to_qs);
-        mNotificationTopPadding = getResources().getDimensionPixelSize(
-                R.dimen.notifications_top_padding);
         mCollapseSecondCardPadding = getResources().getDimensionPixelSize(
                 R.dimen.notification_collapse_second_card_padding);
     }
 
-    private void updatePadding(boolean dimmed) {
-        mPaddingBetweenElements = dimmed && mStackScrollAlgorithm.shouldScaleDimmed()
-                ? mPaddingBetweenElementsDimmed
-                : mPaddingBetweenElementsNormal;
-        mBottomStackSlowDownHeight = mStackScrollAlgorithm.getBottomStackSlowDownLength();
-        updateContentHeight();
-        notifyHeightChangeListener(null);
-    }
-
     private void notifyHeightChangeListener(ExpandableView view) {
         if (mOnHeightChangedListener != null) {
             mOnHeightChangedListener.onHeightChanged(view, false /* needsAnimation */);
@@ -337,10 +388,7 @@
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int mode = MeasureSpec.getMode(widthMeasureSpec);
-        int size = MeasureSpec.getSize(widthMeasureSpec);
-        int childMeasureSpec = MeasureSpec.makeMeasureSpec(size - 2 * mSidePaddings, mode);
-        measureChildren(childMeasureSpec, heightMeasureSpec);
+        measureChildren(widthMeasureSpec, heightMeasureSpec);
     }
 
     @Override
@@ -368,6 +416,7 @@
             mRequestViewResizeAnimationOnLayout = false;
         }
         requestChildrenUpdate();
+        updateFirstAndLastBackgroundViews();
     }
 
     private void requestAnimationOnViewResize(ExpandableNotificationRow row) {
@@ -378,18 +427,6 @@
     }
 
     public void updateSpeedBumpIndex(int newIndex) {
-        int currentIndex = indexOfChild(mSpeedBumpView);
-
-        // If we are currently layouted before the new speed bump index, we have to decrease it.
-        boolean validIndex = newIndex > 0;
-        if (newIndex > getChildCount() - 1) {
-            validIndex = false;
-            newIndex = -1;
-        }
-        if (validIndex && currentIndex != newIndex) {
-            changeViewPosition(mSpeedBumpView, newIndex);
-        }
-        updateSpeedBump(validIndex);
         mAmbientState.setSpeedBumpIndex(newIndex);
     }
 
@@ -686,8 +723,7 @@
         for (int childIdx = 0; childIdx < count; childIdx++) {
             ExpandableView slidingChild = (ExpandableView) getChildAt(childIdx);
             if (slidingChild.getVisibility() == GONE
-                    || slidingChild instanceof StackScrollerDecorView
-                    || slidingChild == mSpeedBumpView) {
+                    || slidingChild instanceof StackScrollerDecorView) {
                 continue;
             }
             float childTop = slidingChild.getTranslationY();
@@ -714,8 +750,7 @@
         for (int childIdx = 0; childIdx < count; childIdx++) {
             ExpandableView slidingChild = (ExpandableView) getChildAt(childIdx);
             if (slidingChild.getVisibility() == GONE
-                    || slidingChild instanceof StackScrollerDecorView
-                    || slidingChild == mSpeedBumpView) {
+                    || slidingChild instanceof StackScrollerDecorView) {
                 continue;
             }
             float childTop = slidingChild.getTranslationY();
@@ -1412,22 +1447,251 @@
 
     private void updateContentHeight() {
         int height = 0;
+        boolean previousNeedsIncreasedPaddings = false;
         for (int i = 0; i < getChildCount(); i++) {
-            View child = getChildAt(i);
-            if (child.getVisibility() != View.GONE) {
+            ExpandableView expandableView = (ExpandableView) getChildAt(i);
+            if (expandableView.getVisibility() != View.GONE) {
+                boolean needsIncreasedPaddings = expandableView.needsIncreasedPadding();
                 if (height != 0) {
-                    // add the padding before this element
-                    height += mPaddingBetweenElements;
+                    int padding = needsIncreasedPaddings || previousNeedsIncreasedPaddings
+                            ? mIncreasedPaddingBetweenElements
+                            : mPaddingBetweenElements;
+                    height += padding;
                 }
-                if (child instanceof ExpandableView) {
-                    ExpandableView expandableView = (ExpandableView) child;
-                    height += expandableView.getIntrinsicHeight();
-                }
+                previousNeedsIncreasedPaddings = needsIncreasedPaddings;
+                height += expandableView.getIntrinsicHeight();
             }
         }
         mContentHeight = height + mTopPadding;
     }
 
+    private void updateBackground() {
+        if (mAmbientState.isDark()) {
+            return;
+        }
+        updateBackgroundBounds();
+        if (!mCurrentBounds.equals(mBackgroundBounds)) {
+            if (mAnimateNextBackgroundTop || mAnimateNextBackgroundBottom || areBoundsAnimating()) {
+                startBackgroundAnimation();
+            } else {
+                mCurrentBounds.set(mBackgroundBounds);
+                applyCurrentBackgroundBounds();
+            }
+        } else {
+            if (mBottomAnimator != null) {
+                mBottomAnimator.cancel();
+            }
+            if (mTopAnimator != null) {
+                mTopAnimator.cancel();
+            }
+        }
+        mAnimateNextBackgroundBottom = false;
+        mAnimateNextBackgroundTop = false;
+    }
+
+    private boolean areBoundsAnimating() {
+        return mBottomAnimator != null || mTopAnimator != null;
+    }
+
+    private void startBackgroundAnimation() {
+        startBottomAnimation();
+        startTopAnimation();
+    }
+
+    private void startTopAnimation() {
+        int previousEndValue = mEndAnimationRect.top;
+        int newEndValue = mBackgroundBounds.top;
+        ObjectAnimator previousAnimator = mTopAnimator;
+        if (previousAnimator != null && previousEndValue == newEndValue) {
+            return;
+        }
+        if (!mAnimateNextBackgroundTop) {
+            // just a local update was performed
+            if (previousAnimator != null) {
+                // we need to increase all animation keyframes of the previous animator by the
+                // relative change to the end value
+                int previousStartValue = mStartAnimationRect.top;
+                PropertyValuesHolder[] values = previousAnimator.getValues();
+                values[0].setIntValues(previousStartValue, newEndValue);
+                mStartAnimationRect.top = previousStartValue;
+                mEndAnimationRect.top = newEndValue;
+                previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+                return;
+            } else {
+                // no new animation needed, let's just apply the value
+                setBackgroundTop(newEndValue);
+                return;
+            }
+        }
+        if (previousAnimator != null) {
+            previousAnimator.cancel();
+        }
+        ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundTop",
+                mCurrentBounds.top, newEndValue);
+        Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
+        animator.setInterpolator(interpolator);
+        animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+        // remove the tag when the animation is finished
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mStartAnimationRect.top = -1;
+                mEndAnimationRect.top = -1;
+                mTopAnimator = null;
+            }
+        });
+        animator.start();
+        mStartAnimationRect.top = mCurrentBounds.top;
+        mEndAnimationRect.top = newEndValue;
+        mTopAnimator = animator;
+    }
+
+    private void startBottomAnimation() {
+        int previousStartValue = mStartAnimationRect.bottom;
+        int previousEndValue = mEndAnimationRect.bottom;
+        int newEndValue = mBackgroundBounds.bottom;
+        ObjectAnimator previousAnimator = mBottomAnimator;
+        if (previousAnimator != null && previousEndValue == newEndValue) {
+            return;
+        }
+        if (!mAnimateNextBackgroundBottom) {
+            // just a local update was performed
+            if (previousAnimator != null) {
+                // we need to increase all animation keyframes of the previous animator by the
+                // relative change to the end value
+                PropertyValuesHolder[] values = previousAnimator.getValues();
+                values[0].setIntValues(previousStartValue, newEndValue);
+                mStartAnimationRect.bottom = previousStartValue;
+                mEndAnimationRect.bottom = newEndValue;
+                previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+                return;
+            } else {
+                // no new animation needed, let's just apply the value
+                setBackgroundBottom(newEndValue);
+                return;
+            }
+        }
+        if (previousAnimator != null) {
+            previousAnimator.cancel();
+        }
+        ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundBottom",
+                mCurrentBounds.bottom, newEndValue);
+        Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
+        animator.setInterpolator(interpolator);
+        animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+        // remove the tag when the animation is finished
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mStartAnimationRect.bottom = -1;
+                mEndAnimationRect.bottom = -1;
+                mBottomAnimator = null;
+            }
+        });
+        animator.start();
+        mStartAnimationRect.bottom = mCurrentBounds.bottom;
+        mEndAnimationRect.bottom = newEndValue;
+        mBottomAnimator = animator;
+    }
+
+    private void setBackgroundTop(int top) {
+        mCurrentBounds.top = top;
+        applyCurrentBackgroundBounds();
+    }
+
+    public void setBackgroundBottom(int bottom) {
+        mCurrentBounds.bottom = bottom;
+        applyCurrentBackgroundBounds();
+    }
+
+    private void applyCurrentBackgroundBounds() {
+        mScrimController.setExcludedBackgroundArea(mCurrentBounds);
+        invalidate();
+    }
+
+    /**
+     * Update the background bounds to the new desired bounds
+     */
+    private void updateBackgroundBounds() {
+        mBackgroundBounds.left = (int) getX();
+        mBackgroundBounds.right = (int) (getX() + getWidth());
+        if (!mIsExpanded) {
+            mBackgroundBounds.top = 0;
+            mBackgroundBounds.bottom = 0;
+        }
+        ActivatableNotificationView firstView = mFirstVisibleBackgroundChild;
+        int top = 0;
+        if (firstView != null) {
+            int finalTranslationY = (int) StackStateAnimator.getFinalTranslationY(firstView);
+            if (mAnimateNextBackgroundTop
+                    || mTopAnimator == null && mCurrentBounds.top == finalTranslationY
+                    || mTopAnimator != null && mEndAnimationRect.top == finalTranslationY) {
+                // we're ending up at the same location as we are now, lets just skip the animation
+                top = finalTranslationY;
+            } else {
+                top = (int) firstView.getTranslationY();
+            }
+        }
+        ActivatableNotificationView lastView = mLastVisibleBackgroundChild;
+        int bottom = 0;
+        if (lastView != null) {
+            int finalTranslationY = (int) StackStateAnimator.getFinalTranslationY(lastView);
+            int finalHeight = StackStateAnimator.getFinalActualHeight(lastView);
+            int finalBottom = finalTranslationY + finalHeight;
+            finalBottom = Math.min(finalBottom, getHeight());
+            if (mAnimateNextBackgroundBottom
+                    || mBottomAnimator == null && mCurrentBounds.bottom == finalBottom
+                    || mBottomAnimator != null && mEndAnimationRect.bottom == finalBottom) {
+                // we're ending up at the same location as we are now, lets just skip the animation
+                bottom = finalBottom;
+            } else {
+                bottom = (int) (lastView.getTranslationY() + lastView.getActualHeight());
+                bottom = Math.min(bottom, getHeight());
+            }
+        }
+        mBackgroundBounds.top = top;
+        mBackgroundBounds.bottom = bottom;
+    }
+
+    private ActivatableNotificationView getFirstPinnedHeadsUp() {
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View child = getChildAt(i);
+            if (child.getVisibility() != View.GONE
+                    && child instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+                if (row.isPinned()) {
+                    return row;
+                }
+            }
+        }
+        return null;
+    }
+
+    private ActivatableNotificationView getLastChildWithBackground() {
+        int childCount = getChildCount();
+        for (int i = childCount - 1; i >= 0; i--) {
+            View child = getChildAt(i);
+            if (child.getVisibility() != View.GONE
+                    && child instanceof ActivatableNotificationView) {
+                return (ActivatableNotificationView) child;
+            }
+        }
+        return null;
+    }
+
+    private ActivatableNotificationView getFirstChildWithBackground() {
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View child = getChildAt(i);
+            if (child.getVisibility() != View.GONE
+                    && child instanceof ActivatableNotificationView) {
+                return (ActivatableNotificationView) child;
+            }
+        }
+        return null;
+    }
+
     /**
      * Fling the scroll view
      *
@@ -1489,7 +1753,7 @@
      */
     public void updateTopPadding(float qsHeight, int scrollY, boolean animate,
             boolean ignoreIntrinsicPadding) {
-        float start = qsHeight - scrollY + mNotificationTopPadding;
+        float start = qsHeight - scrollY;
         float stackHeight = getHeight() - start;
         int minStackHeight = getMinStackHeight();
         if (stackHeight <= minStackHeight) {
@@ -1505,10 +1769,6 @@
         setStackHeight(mLastSetStackHeight);
     }
 
-    public int getNotificationTopPadding() {
-        return mNotificationTopPadding;
-    }
-
     public int getMinStackHeight() {
         final ExpandableView firstChild = getFirstChildNotGone();
         final int firstChildMinHeight = firstChild != null ? firstChild.getMinHeight()
@@ -1655,7 +1915,7 @@
         }
         ((ExpandableView) child).setOnHeightChangedListener(null);
         mCurrentStackScrollState.removeViewStateForView(child);
-        updateScrollStateForRemovedChild(child);
+        updateScrollStateForRemovedChild((ExpandableView) child);
         boolean animationGenerated = generateRemoveAnimation(child);
         if (animationGenerated && !mSwipedOutViews.contains(child)) {
             // Add this view to an overlay in order to ensure that it will still be temporary
@@ -1754,9 +2014,12 @@
      *
      * @param removedChild the removed child
      */
-    private void updateScrollStateForRemovedChild(View removedChild) {
+    private void updateScrollStateForRemovedChild(ExpandableView removedChild) {
         int startingPosition = getPositionInLinearLayout(removedChild);
-        int childHeight = getIntrinsicHeight(removedChild) + mPaddingBetweenElements;
+        int padding = removedChild.needsIncreasedPadding()
+                ? mIncreasedPaddingBetweenElements :
+                mPaddingBetweenElements;
+        int childHeight = getIntrinsicHeight(removedChild) + padding;
         int endPosition = startingPosition + childHeight;
         if (endPosition <= mOwnScrollY) {
             // This child is fully scrolled of the top, so we have to deduct its height from the
@@ -1779,16 +2042,25 @@
 
     private int getPositionInLinearLayout(View requestedChild) {
         int position = 0;
+        boolean previousNeedsIncreasedPaddings = false;
         for (int i = 0; i < getChildCount(); i++) {
-            View child = getChildAt(i);
+            ExpandableView child = (ExpandableView) getChildAt(i);
+            boolean notGone = child.getVisibility() != View.GONE;
+            if (notGone) {
+                boolean needsIncreasedPaddings = child.needsIncreasedPadding();
+                if (position != 0) {
+                    int padding = needsIncreasedPaddings || previousNeedsIncreasedPaddings
+                            ? mIncreasedPaddingBetweenElements :
+                            mPaddingBetweenElements;
+                    position += padding;
+                }
+                previousNeedsIncreasedPaddings = needsIncreasedPaddings;
+            }
             if (child == requestedChild) {
                 return position;
             }
-            if (child.getVisibility() != View.GONE) {
+            if (notGone) {
                 position += getIntrinsicHeight(child);
-                if (i < getChildCount()-1) {
-                    position += mPaddingBetweenElements;
-                }
             }
         }
         return 0;
@@ -1800,6 +2072,20 @@
         onViewAddedInternal(child);
     }
 
+    private void updateFirstAndLastBackgroundViews() {
+        ActivatableNotificationView firstChild = getFirstChildWithBackground();
+        ActivatableNotificationView lastChild = getLastChildWithBackground();
+        if (mAnimationsEnabled && mIsExpanded) {
+            mAnimateNextBackgroundTop = firstChild != mFirstVisibleBackgroundChild;
+            mAnimateNextBackgroundBottom = lastChild != mLastVisibleBackgroundChild;
+        } else {
+            mAnimateNextBackgroundTop = false;
+            mAnimateNextBackgroundBottom = false;
+        }
+        mFirstVisibleBackgroundChild = firstChild;
+        mLastVisibleBackgroundChild = lastChild;
+    }
+
     private void onViewAddedInternal(View child) {
         updateHideSensitiveForChild(child);
         mStackScrollAlgorithm.notifyChildrenChanged(this);
@@ -1910,7 +2196,9 @@
         if (!mAnimationEvents.isEmpty() || isCurrentlyAnimating()) {
             mStateAnimator.startAnimationForEvents(mAnimationEvents, mCurrentStackScrollState,
                     mGoToFullShadeDelay);
+            setAnimationRunning(true);
             mAnimationEvents.clear();
+            updateBackground();
         } else {
             applyCurrentState();
         }
@@ -2396,6 +2684,7 @@
     }
 
     public void onChildAnimationFinished() {
+        setAnimationRunning(false);
         requestChildrenUpdate();
         runAnimationFinishedRunnables();
         clearViewOverlays();
@@ -2418,16 +2707,38 @@
      * See {@link AmbientState#setDimmed}.
      */
     public void setDimmed(boolean dimmed, boolean animate) {
-        mStackScrollAlgorithm.setDimmed(dimmed);
         mAmbientState.setDimmed(dimmed);
-        updatePadding(dimmed);
         if (animate && mAnimationsEnabled) {
             mDimmedNeedsAnimation = true;
             mNeedsAnimation =  true;
+            animateDimmed(dimmed);
+        } else {
+            setDimAmount(dimmed ? 1.0f : 0.0f);
         }
         requestChildrenUpdate();
     }
 
+    private void setDimAmount(float dimAmount) {
+        mDimAmount = dimAmount;
+        updateBackgroundDimming();
+    }
+
+    private void animateDimmed(boolean dimmed) {
+        if (mDimAnimator != null) {
+            mDimAnimator.cancel();
+        }
+        float target = dimmed ? 1.0f : 0.0f;
+        if (target == mDimAmount) {
+            return;
+        }
+        mDimAnimator = TimeAnimator.ofFloat(mDimAmount, target);
+        mDimAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_DIMMED_ACTIVATED);
+        mDimAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        mDimAnimator.addListener(mDimEndListener);
+        mDimAnimator.addUpdateListener(mDimUpdateListener);
+        mDimAnimator.start();
+    }
+
     public void setHideSensitive(boolean hideSensitive, boolean animate) {
         if (hideSensitive != mAmbientState.isHideSensitive()) {
             int childCount = getChildCount();
@@ -2466,30 +2777,10 @@
             mListener.onChildLocationsChanged(this);
         }
         runAnimationFinishedRunnables();
-    }
-
-    public void setSpeedBumpView(SpeedBumpView speedBumpView) {
-        mSpeedBumpView = speedBumpView;
-        addView(speedBumpView);
-    }
-
-    private void updateSpeedBump(boolean visible) {
-        boolean notGoneBefore = mSpeedBumpView.getVisibility() != GONE;
-        if (visible != notGoneBefore) {
-            int newVisibility = visible ? VISIBLE : GONE;
-            mSpeedBumpView.setVisibility(newVisibility);
-            if (visible) {
-                // Make invisible to ensure that the appear animation is played.
-                mSpeedBumpView.setInvisible();
-            } else {
-                // TODO: This doesn't really work, because the view is already set to GONE above.
-                generateRemoveAnimation(mSpeedBumpView);
-            }
-        }
+        updateBackground();
     }
 
     public void goToFullShade(long delay) {
-        updateSpeedBump(true /* visibility */);
         mDismissView.setInvisible();
         mEmptyShadeView.setInvisible();
         mGoToFullShadeNeedsAnimation = true;
@@ -2533,6 +2824,14 @@
             mNeedsAnimation =  true;
         }
         requestChildrenUpdate();
+        if (dark) {
+            setWillNotDraw(!DEBUG);
+            mScrimController.setExcludedBackgroundArea(null);
+        } else {
+            updateBackground();
+            setWillNotDraw(false);
+            // TODO: fade in background
+        }
     }
 
     private int findDarkAnimationOriginIndex(@Nullable PointF screenLocation) {
@@ -2731,7 +3030,7 @@
     }
 
     public int getDismissViewHeight() {
-        int height = mDismissView.getHeight() + mPaddingBetweenElementsNormal;
+        int height = mDismissView.getHeight() + mPaddingBetweenElements;
 
         // Hack: Accommodate for additional distance when we only have one notification and the
         // dismiss all button.
@@ -2881,6 +3180,12 @@
 
     public void setScrimController(ScrimController scrimController) {
         mScrimController = scrimController;
+        mScrimController.setScrimBehindChangeRunnable(new Runnable() {
+            @Override
+            public void run() {
+                updateBackgroundDimming();
+            }
+        });
     }
 
     public void forceNoOverlappingRendering(boolean force) {
@@ -2892,6 +3197,17 @@
         return !mForceNoOverlappingRendering && super.hasOverlappingRendering();
     }
 
+    public void setAnimationRunning(boolean animationRunning) {
+        if (animationRunning != mAnimationRunning) {
+            if (animationRunning) {
+                getViewTreeObserver().addOnPreDrawListener(mBackgroundUpdater);
+            } else {
+                getViewTreeObserver().removeOnPreDrawListener(mBackgroundUpdater);
+            }
+            mAnimationRunning = animationRunning;
+        }
+    }
+
     /**
      * A listener that is notified when some child locations might have changed.
      */
@@ -2937,7 +3253,7 @@
 
                 // ANIMATION_TYPE_ADD
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -2946,7 +3262,7 @@
 
                 // ANIMATION_TYPE_REMOVE
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -2955,7 +3271,7 @@
 
                 // ANIMATION_TYPE_REMOVE_SWIPED_OUT
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -2964,37 +3280,35 @@
 
                 // ANIMATION_TYPE_TOP_PADDING_CHANGED
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
                         .animateDimmed()
-                        .animateScale()
                         .animateZ(),
 
                 // ANIMATION_TYPE_START_DRAG
                 new AnimationFilter()
-                        .animateAlpha(),
+                        .animateShadowAlpha(),
 
                 // ANIMATION_TYPE_SNAP_BACK
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight(),
 
                 // ANIMATION_TYPE_ACTIVATED_CHILD
                 new AnimationFilter()
-                        .animateScale()
-                        .animateAlpha(),
+                        .animateZ(),
 
                 // ANIMATION_TYPE_DIMMED
                 new AnimationFilter()
                         .animateY()
-                        .animateScale()
                         .animateDimmed(),
 
                 // ANIMATION_TYPE_CHANGE_POSITION
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateAlpha() // maybe the children change positions
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -3007,12 +3321,11 @@
 
                 // ANIMATION_TYPE_GO_TO_FULL_SHADE
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
                         .animateDimmed()
-                        .animateScale()
                         .animateZ()
                         .hasDelays(),
 
@@ -3022,7 +3335,7 @@
 
                 // ANIMATION_TYPE_VIEW_RESIZE
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -3031,6 +3344,7 @@
                 // ANIMATION_TYPE_GROUP_EXPANSION_CHANGED
                 new AnimationFilter()
                         .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -3038,7 +3352,7 @@
 
                 // ANIMATION_TYPE_HEADS_UP_APPEAR
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -3046,7 +3360,7 @@
 
                 // ANIMATION_TYPE_HEADS_UP_DISAPPEAR
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -3054,7 +3368,7 @@
 
                 // ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -3063,7 +3377,7 @@
 
                 // ANIMATION_TYPE_HEADS_UP_OTHER
                 new AnimationFilter()
-                        .animateAlpha()
+                        .animateShadowAlpha()
                         .animateHeight()
                         .animateTopInset()
                         .animateY()
@@ -3072,8 +3386,8 @@
                 // ANIMATION_TYPE_EVERYTHING
                 new AnimationFilter()
                         .animateAlpha()
+                        .animateShadowAlpha()
                         .animateDark()
-                        .animateScale()
                         .animateDimmed()
                         .animateHideSensitive()
                         .animateHeight()
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 822012d..f6959f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.stack;
 
 import android.content.Context;
-import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -27,6 +26,7 @@
 import com.android.systemui.statusbar.ExpandableView;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 
 /**
@@ -41,15 +41,13 @@
     private static final int MAX_ITEMS_IN_BOTTOM_STACK = 3;
     private static final int MAX_ITEMS_IN_TOP_STACK = 3;
 
-    public static final float DIMMED_SCALE = 0.98f;
-
     private int mPaddingBetweenElements;
+    private int mIncreasedPaddingBetweenElements;
     private int mCollapsedSize;
     private int mTopStackPeekSize;
     private int mBottomStackPeekSize;
     private int mZDistanceBetweenElements;
     private int mZBasicHeight;
-    private int mRoundedRectCornerRadius;
 
     private StackIndentationFunctor mTopStackIndentationFunctor;
     private StackIndentationFunctor mBottomStackIndentationFunctor;
@@ -61,16 +59,11 @@
     private ExpandableView mFirstChildWhileExpanding;
     private boolean mExpandedOnStart;
     private int mTopStackTotalSize;
-    private int mPaddingBetweenElementsDimmed;
-    private int mPaddingBetweenElementsNormal;
-    private int mNotificationsTopPadding;
     private int mBottomStackSlowDownLength;
     private int mTopStackSlowDownLength;
     private int mCollapseSecondCardPadding;
-    private boolean mScaleDimmed;
     private ExpandableView mFirstChild;
     private int mFirstChildMinHeight;
-    private boolean mDimmed;
 
     public StackScrollAlgorithm(Context context) {
         initView(context);
@@ -82,9 +75,6 @@
     }
 
     private void updatePadding() {
-        mPaddingBetweenElements = mDimmed && mScaleDimmed
-                ? mPaddingBetweenElementsDimmed
-                : mPaddingBetweenElementsNormal;
         mTopStackTotalSize = mTopStackSlowDownLength + mPaddingBetweenElements
                 + mTopStackPeekSize;
         mTopStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
@@ -104,35 +94,25 @@
     }
 
     private void initConstants(Context context) {
-        mPaddingBetweenElementsDimmed = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_padding_dimmed);
-        mPaddingBetweenElementsNormal = context.getResources()
-                .getDimensionPixelSize(R.dimen.notification_padding);
-        mNotificationsTopPadding = context.getResources()
-                .getDimensionPixelSize(R.dimen.notifications_top_padding);
+        mPaddingBetweenElements = Math.max(1, context.getResources()
+                .getDimensionPixelSize(R.dimen.notification_divider_height));
+        mIncreasedPaddingBetweenElements = context.getResources()
+                .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 = context.getResources()
-                .getDimensionPixelSize(R.dimen.z_distance_between_notifications);
+        mZDistanceBetweenElements = Math.max(1, context.getResources()
+                .getDimensionPixelSize(R.dimen.z_distance_between_notifications));
         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);
-        mRoundedRectCornerRadius = context.getResources().getDimensionPixelSize(
-                R.dimen.notification_material_rounded_rect_radius);
         mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize(
                 R.dimen.notification_collapse_second_card_padding);
-        mScaleDimmed = context.getResources().getDisplayMetrics().densityDpi
-                >= DisplayMetrics.DENSITY_420;
-    }
-
-    public boolean shouldScaleDimmed() {
-        return mScaleDimmed;
     }
 
     public void getStackScrollState(AmbientState ambientState, StackScrollState resultState) {
@@ -159,7 +139,7 @@
         scrollY = Math.max(0, scrollY);
         algorithmState.scrollY = (int) (scrollY + mFirstChildMinHeight + bottomOverScroll);
 
-        updateVisibleChildren(resultState, algorithmState);
+        initAlgorithmState(resultState, algorithmState);
 
         // Phase 1:
         findNumberOfItemsInTopStackAndUpdateState(resultState, algorithmState, ambientState);
@@ -212,8 +192,8 @@
         for (int i = 0; i < childCount; i++) {
             ExpandableView child = algorithmState.visibleChildren.get(i);
             StackViewState state = resultState.getViewStateForView(child);
-            float newYTranslation = state.yTranslation + state.height * (1f - state.scale) / 2f;
-            float newHeight = state.height * state.scale;
+            float newYTranslation = state.yTranslation;
+            float newHeight = state.height;
             // apply clipping and shadow
             float newNotificationEnd = newYTranslation + newHeight;
 
@@ -225,16 +205,6 @@
             } else {
                 clipHeight = newNotificationEnd - previousNotificationEnd;
                 clipHeight = Math.max(0.0f, clipHeight);
-                if (clipHeight != 0.0f) {
-
-                    // In the unlocked shade we have to clip a little bit higher because of the rounded
-                    // corners of the notifications, but only if we are not fully overlapped by
-                    // the top card.
-                    float clippingCorrection = state.dimmed
-                            ? 0
-                            : mRoundedRectCornerRadius * state.scale;
-                    clipHeight += clippingCorrection;
-                }
             }
 
             updateChildClippingAndBackground(state, newHeight, clipHeight,
@@ -252,7 +222,7 @@
                 } else {
                     previousNotificationIsSwiped = ambientState.getDraggedViews().contains(child);
                     previousNotificationEnd = newNotificationEnd;
-                    previousNotificationStart = newYTranslation + state.clipTopAmount * state.scale;
+                    previousNotificationStart = newYTranslation + state.clipTopAmount;
                 }
             }
         }
@@ -276,13 +246,13 @@
             float clipHeight, float backgroundHeight) {
         if (realHeight > clipHeight) {
             // Rather overlap than create a hole.
-            state.topOverLap = (int) Math.floor((realHeight - clipHeight) / state.scale);
+            state.topOverLap = (int) Math.floor(realHeight - clipHeight);
         } else {
             state.topOverLap = 0;
         }
         if (realHeight > backgroundHeight) {
             // Rather overlap than create a hole.
-            state.clipTopAmount = (int) Math.floor((realHeight - backgroundHeight) / state.scale);
+            state.clipTopAmount = (int) Math.floor(realHeight - backgroundHeight);
         } else {
             state.clipTopAmount = 0;
         }
@@ -305,9 +275,6 @@
             childViewState.dark = dark;
             childViewState.hideSensitive = hideSensitive;
             boolean isActivatedChild = activatedChild == child;
-            childViewState.scale = !mScaleDimmed || !dimmed || isActivatedChild
-                    ? 1.0f
-                    : DIMMED_SCALE;
             if (dimmed && isActivatedChild) {
                 childViewState.zTranslation += 2.0f * mZDistanceBetweenElements;
             }
@@ -331,7 +298,8 @@
                             nextChild);
                     // The child below the dragged one must be fully visible
                     if (ambientState.isShadeExpanded()) {
-                        viewState.alpha = 1;
+                        viewState.shadowAlpha = 1;
+                        viewState.hidden = false;
                     }
                 }
 
@@ -344,19 +312,28 @@
     }
 
     /**
-     * Update the visible children on the state.
+     * Initialize the algorithm state like updating the visible children.
      */
-    private void updateVisibleChildren(StackScrollState resultState,
+    private void initAlgorithmState(StackScrollState resultState,
             StackScrollAlgorithmState state) {
         ViewGroup hostView = resultState.getHostView();
         int childCount = hostView.getChildCount();
         state.visibleChildren.clear();
         state.visibleChildren.ensureCapacity(childCount);
+        state.increasedPaddingSet.clear();
         int notGoneIndex = 0;
+        ExpandableView lastView = null;
         for (int i = 0; i < childCount; i++) {
             ExpandableView v = (ExpandableView) hostView.getChildAt(i);
             if (v.getVisibility() != View.GONE) {
                 notGoneIndex = updateNotGoneIndex(resultState, state, notGoneIndex, v);
+                boolean needsIncreasedPadding = v.needsIncreasedPadding();
+                if (needsIncreasedPadding) {
+                    state.increasedPaddingSet.add(v);
+                    if (lastView != null) {
+                        state.increasedPaddingSet.add(lastView);
+                    }
+                }
                 if (v instanceof ExpandableNotificationRow) {
                     ExpandableNotificationRow row = (ExpandableNotificationRow) v;
 
@@ -374,6 +351,7 @@
                         }
                     }
                 }
+                lastView = v;
             }
         }
     }
@@ -414,15 +392,17 @@
         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);
             StackViewState childViewState = resultState.getViewStateForView(child);
             childViewState.location = StackViewState.LOCATION_UNKNOWN;
+            paddingAfterChild = getPaddingAfterChild(algorithmState, child);
             int childHeight = getMaxAllowedChildHeight(child);
             int minHeight = child.getMinHeight();
             float yPositionInScrollViewAfterElement = yPositionInScrollView
                     + childHeight
-                    + mPaddingBetweenElements;
+                    + paddingAfterChild;
             float scrollOffset = yPositionInScrollView - algorithmState.scrollY +
                     mFirstChildMinHeight;
 
@@ -437,20 +417,20 @@
 
             // The y position after this element
             float nextYPosition = currentYPosition + childHeight +
-                    mPaddingBetweenElements;
+                    paddingAfterChild;
 
             if (i <= algorithmState.lastTopStackIndex) {
                 // Case 1:
                 // We are in the top Stack
-                updateStateForTopStackChild(algorithmState,
+                updateStateForTopStackChild(algorithmState, child,
                         numberOfElementsCompletelyIn, i, childHeight, childViewState, scrollOffset);
                 clampPositionToTopStackEnd(childViewState, childHeight);
 
                 // check if we are overlapping with the bottom stack
-                if (childViewState.yTranslation + childHeight + mPaddingBetweenElements
+                if (childViewState.yTranslation + childHeight + paddingAfterChild
                         >= bottomStackStart && !mIsExpansionChanging && i != 0) {
                     // we just collapse this element slightly
-                    int newSize = (int) Math.max(bottomStackStart - mPaddingBetweenElements -
+                    int newSize = (int) Math.max(bottomStackStart - paddingAfterChild -
                             childViewState.yTranslation, minHeight);
                     childViewState.height = newSize;
                     updateStateForChildTransitioningInBottom(algorithmState, bottomStackStart,
@@ -466,7 +446,7 @@
                     // According to the regular scroll view we are fully translated out of the
                     // bottom of the screen so we are fully in the bottom stack
                     updateStateForChildFullyInBottomStack(algorithmState,
-                            bottomStackStart, childViewState, minHeight, ambientState);
+                            bottomStackStart, childViewState, minHeight, ambientState, child);
                 } else {
                     // According to the regular scroll view we are currently translating out of /
                     // into the bottom of the screen
@@ -483,7 +463,8 @@
 
             // The first card is always rendered.
             if (i == 0) {
-                childViewState.alpha = 1.0f;
+                childViewState.hidden = false;
+                childViewState.shadowAlpha = 1.0f;
                 childViewState.yTranslation = Math.max(
                         mFirstChildMinHeight - algorithmState.scrollY, 0);
                 if (childViewState.yTranslation + childViewState.height
@@ -497,7 +478,7 @@
             if (childViewState.location == StackViewState.LOCATION_UNKNOWN) {
                 Log.wtf(LOG_TAG, "Failed to assign location for child " + i);
             }
-            currentYPosition = childViewState.yTranslation + childHeight + mPaddingBetweenElements;
+            currentYPosition = childViewState.yTranslation + childHeight + paddingAfterChild;
             yPositionInScrollView = yPositionInScrollViewAfterElement;
 
             childViewState.yTranslation += ambientState.getTopPadding()
@@ -506,6 +487,13 @@
         updateHeadsUpStates(resultState, algorithmState, ambientState);
     }
 
+    private int getPaddingAfterChild(StackScrollAlgorithmState algorithmState,
+            ExpandableView child) {
+        return algorithmState.increasedPaddingSet.contains(child)
+                ? mIncreasedPaddingBetweenElements
+                : mPaddingBetweenElements;
+    }
+
     private void updateHeadsUpStates(StackScrollState resultState,
             StackScrollAlgorithmState algorithmState, AmbientState ambientState) {
         int childCount = algorithmState.visibleChildren.size();
@@ -530,8 +518,7 @@
                         bottomPosition);
             }
             if (row.isPinned()) {
-                childState.yTranslation = Math.max(childState.yTranslation,
-                        mNotificationsTopPadding);
+                childState.yTranslation = Math.max(childState.yTranslation, 0);
                 childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
                 if (!isTopEntry) {
                     // Ensure that a headsUp doesn't vertically extend further than the heads-up at
@@ -610,7 +597,7 @@
         // This is the transitioning element on top of bottom stack, calculate how far we are in.
         algorithmState.partialInBottom = 1.0f - (
                 (transitioningPositionStart - currentYPosition) / (childHeight +
-                        mPaddingBetweenElements));
+                        getPaddingAfterChild(algorithmState, child)));
 
         // the offset starting at the transitionPosition of the bottom stack
         float offset = mBottomStackIndentationFunctor.getValue(algorithmState.partialInBottom);
@@ -618,12 +605,12 @@
         int newHeight = childHeight;
         if (childHeight > child.getMinHeight()) {
             newHeight = (int) Math.max(Math.min(transitioningPositionStart + offset -
-                    mPaddingBetweenElements - currentYPosition, childHeight),
+                    getPaddingAfterChild(algorithmState, child) - currentYPosition, childHeight),
                     child.getMinHeight());
             childViewState.height = newHeight;
         }
         childViewState.yTranslation = transitioningPositionStart + offset - newHeight
-                - mPaddingBetweenElements;
+                - getPaddingAfterChild(algorithmState, child);
 
         // We want at least to be at the end of the top stack when collapsing
         clampPositionToTopStackEnd(childViewState, newHeight);
@@ -632,22 +619,23 @@
 
     private void updateStateForChildFullyInBottomStack(StackScrollAlgorithmState algorithmState,
             float transitioningPositionStart, StackViewState childViewState,
-            int minHeight, AmbientState ambientState) {
+            int minHeight, AmbientState ambientState, ExpandableView child) {
         float currentYPosition;
         algorithmState.itemsInBottomStack += 1.0f;
         if (algorithmState.itemsInBottomStack < MAX_ITEMS_IN_BOTTOM_STACK) {
             // We are visually entering the bottom stack
             currentYPosition = transitioningPositionStart
                     + mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack)
-                    - mPaddingBetweenElements;
+                    - getPaddingAfterChild(algorithmState, child);
             childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_PEEKING;
         } else {
             // we are fully inside the stack
             if (algorithmState.itemsInBottomStack > MAX_ITEMS_IN_BOTTOM_STACK + 2) {
-                childViewState.alpha = 0.0f;
+                childViewState.hidden = true;
+                childViewState.shadowAlpha = 0.0f;
             } else if (algorithmState.itemsInBottomStack
                     > MAX_ITEMS_IN_BOTTOM_STACK + 1) {
-                childViewState.alpha = 1.0f - algorithmState.partialInBottom;
+                childViewState.shadowAlpha = 1.0f - algorithmState.partialInBottom;
             }
             childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_HIDDEN;
             currentYPosition = ambientState.getInnerHeight();
@@ -658,7 +646,7 @@
     }
 
     private void updateStateForTopStackChild(StackScrollAlgorithmState algorithmState,
-            int numberOfElementsCompletelyIn, int i, int childHeight,
+            ExpandableView child, int numberOfElementsCompletelyIn, int i, int childHeight,
             StackViewState childViewState, float scrollOffset) {
 
 
@@ -669,10 +657,11 @@
         if (paddedIndex >= 0) {
 
             // We are currently visually entering the top stack
-            float distanceToStack = (childHeight + mPaddingBetweenElements)
+            float distanceToStack = (childHeight + getPaddingAfterChild(algorithmState, child))
                     - algorithmState.scrolledPixelsTop;
             if (i == algorithmState.lastTopStackIndex
-                    && distanceToStack > (mTopStackTotalSize + mPaddingBetweenElements)) {
+                    && distanceToStack > (mTopStackTotalSize
+                    + getPaddingAfterChild(algorithmState, child))) {
 
                 // Child is currently translating into stack but not yet inside slow down zone.
                 // Handle it like the regular scrollview.
@@ -682,7 +671,8 @@
                 float numItemsBefore;
                 if (i == algorithmState.lastTopStackIndex) {
                     numItemsBefore = 1.0f
-                            - (distanceToStack / (mTopStackTotalSize + mPaddingBetweenElements));
+                            - (distanceToStack / (mTopStackTotalSize
+                            + getPaddingAfterChild(algorithmState, child)));
                 } else {
                     numItemsBefore = algorithmState.itemsInTopStack - i;
                 }
@@ -694,10 +684,11 @@
             childViewState.location = StackViewState.LOCATION_TOP_STACK_PEEKING;
         } else {
             if (paddedIndex == -1) {
-                childViewState.alpha = 1.0f - algorithmState.partialInTop;
+                childViewState.shadowAlpha = 1.0f - algorithmState.partialInTop;
             } else {
                 // We are hidden behind the top card and faded out, so we can hide ourselves.
-                childViewState.alpha = 0.0f;
+                childViewState.hidden = true;
+                childViewState.shadowAlpha = 0.0f;
             }
             childViewState.yTranslation = mFirstChildMinHeight - childHeight;
             childViewState.location = StackViewState.LOCATION_TOP_STACK_HIDDEN;
@@ -718,15 +709,15 @@
         // 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
-                    + mPaddingBetweenElements;
+                    + paddingAfterChild;
             if (yPositionInScrollView < algorithmState.scrollY) {
                 if (i == 0 && algorithmState.scrollY <= mFirstChildMinHeight) {
 
@@ -754,7 +745,7 @@
                     algorithmState.scrolledPixelsTop = algorithmState.scrollY
                             - yPositionInScrollView;
                     algorithmState.partialInTop = (algorithmState.scrolledPixelsTop) / (childHeight
-                            + mPaddingBetweenElements);
+                            + paddingAfterChild);
 
                     // Our element can be expanded, so this can get negative
                     algorithmState.partialInTop = Math.max(0.0f, algorithmState.partialInTop);
@@ -763,7 +754,7 @@
                     if (i == 0) {
                         // If it is expanded we have to collapse it to a new size
                         float newSize = yPositionInScrollViewAfterElement
-                                - mPaddingBetweenElements
+                                - paddingAfterChild
                                 - algorithmState.scrollY + mFirstChildMinHeight;
                         newSize = Math.max(mFirstChildMinHeight, newSize);
                         algorithmState.itemsInTopStack = 1.0f;
@@ -917,11 +908,6 @@
         }
     }
 
-    public void setDimmed(boolean dimmed) {
-        mDimmed = dimmed;
-        updatePadding();
-    }
-
     public void onReset(ExpandableView view) {
         if (view.equals(mFirstChildWhileExpanding)) {
             updateFirstChildMaxSizeToMaxHeight();
@@ -969,6 +955,11 @@
          * The children from the host view which are not gone.
          */
         public final ArrayList<ExpandableView> visibleChildren = new ArrayList<ExpandableView>();
+
+        /**
+         * The children from the host that need an increased padding after them.
+         */
+        public final HashSet<ExpandableView> increasedPaddingSet = new HashSet<>();
     }
 
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index e155d70..1fedc1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -25,7 +25,6 @@
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
-import com.android.systemui.statusbar.SpeedBumpView;
 
 import java.util.HashMap;
 import java.util.List;
@@ -83,8 +82,10 @@
         // initialize with the default values of the view
         viewState.height = view.getIntrinsicHeight();
         viewState.gone = view.getVisibility() == View.GONE;
-        viewState.alpha = 1;
+        viewState.alpha = 1f;
+        viewState.shadowAlpha = 1f;
         viewState.notGoneIndex = -1;
+        viewState.hidden = false;
     }
 
     public StackViewState getViewStateForView(View requestedView) {
@@ -107,9 +108,7 @@
             if (!applyState(child, state)) {
                 continue;
             }
-            if(child instanceof SpeedBumpView) {
-                performSpeedBumpAnimation(i, (SpeedBumpView) child, state, 0);
-            } else if (child instanceof DismissView) {
+            if (child instanceof DismissView) {
                 DismissView dismissView = (DismissView) child;
                 boolean visible = state.topOverLap < mClearAllTopPadding;
                 dismissView.performVisibilityAnimation(visible && !dismissView.willBeGone());
@@ -146,6 +145,14 @@
             view.setActualHeight(newHeight, false /* notifyListeners */);
         }
 
+        float shadowAlpha = view.getShadowAlpha();
+        float newShadowAlpha = state.shadowAlpha;
+
+        // apply shadowAlpha
+        if (shadowAlpha != newShadowAlpha) {
+            view.setShadowAlpha(newShadowAlpha);
+        }
+
         // apply dimming
         view.setDimmed(state.dimmed, false /* animate */);
 
@@ -183,12 +190,10 @@
         float yTranslation = view.getTranslationY();
         float xTranslation = view.getTranslationX();
         float zTranslation = view.getTranslationZ();
-        float scale = view.getScaleX();
         float newAlpha = state.alpha;
         float newYTranslation = state.yTranslation;
         float newZTranslation = state.zTranslation;
-        float newScale = state.scale;
-        boolean becomesInvisible = newAlpha == 0.0f;
+        boolean becomesInvisible = newAlpha == 0.0f || state.hidden;
         if (alpha != newAlpha && xTranslation == 0) {
             // apply layer type
             boolean becomesFullyVisible = newAlpha == 1.0f;
@@ -225,34 +230,5 @@
         if (zTranslation != newZTranslation) {
             view.setTranslationZ(newZTranslation);
         }
-
-        // apply scale
-        if (scale != newScale) {
-            view.setScaleX(newScale);
-            view.setScaleY(newScale);
-        }
     }
-
-    public void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, StackViewState state,
-            long delay) {
-        View nextChild = getNextChildNotGone(i);
-        if (nextChild != null) {
-            float lineEnd = state.yTranslation + state.height / 2;
-            StackViewState nextState = getViewStateForView(nextChild);
-            boolean startIsAboveNext = nextState.yTranslation > lineEnd;
-            speedBump.animateDivider(startIsAboveNext, delay, null /* onFinishedRunnable */);
-        }
-    }
-
-    private View getNextChildNotGone(int childIndex) {
-        int childCount = mHostView.getChildCount();
-        for (int i = childIndex + 1; i < childCount; i++) {
-            View child = mHostView.getChildAt(i);
-            if (child.getVisibility() != View.GONE) {
-                return child;
-            }
-        }
-        return null;
-    }
-
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 9d5e072..e75e8e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -22,13 +22,12 @@
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
 import android.view.View;
-import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
-import com.android.systemui.statusbar.SpeedBumpView;
+import com.android.systemui.statusbar.Interpolators;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import java.util.ArrayList;
@@ -55,24 +54,23 @@
 
     private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
     private static final int TAG_ANIMATOR_TRANSLATION_Z = R.id.translation_z_animator_tag;
-    private static final int TAG_ANIMATOR_SCALE = R.id.scale_animator_tag;
     private static final int TAG_ANIMATOR_ALPHA = R.id.alpha_animator_tag;
     private static final int TAG_ANIMATOR_HEIGHT = R.id.height_animator_tag;
     private static final int TAG_ANIMATOR_TOP_INSET = R.id.top_inset_animator_tag;
+    private static final int TAG_ANIMATOR_SHADOW_ALPHA = R.id.shadow_alpha_animator_tag;
     private static final int TAG_END_TRANSLATION_Y = R.id.translation_y_animator_end_value_tag;
     private static final int TAG_END_TRANSLATION_Z = R.id.translation_z_animator_end_value_tag;
-    private static final int TAG_END_SCALE = R.id.scale_animator_end_value_tag;
     private static final int TAG_END_ALPHA = R.id.alpha_animator_end_value_tag;
     private static final int TAG_END_HEIGHT = R.id.height_animator_end_value_tag;
     private static final int TAG_END_TOP_INSET = R.id.top_inset_animator_end_value_tag;
+    private static final int TAG_END_SHADOW_ALPHA = R.id.shadow_alpha_animator_end_value_tag;
     private static final int TAG_START_TRANSLATION_Y = R.id.translation_y_animator_start_value_tag;
     private static final int TAG_START_TRANSLATION_Z = R.id.translation_z_animator_start_value_tag;
-    private static final int TAG_START_SCALE = R.id.scale_animator_start_value_tag;
     private static final int TAG_START_ALPHA = R.id.alpha_animator_start_value_tag;
     private static final int TAG_START_HEIGHT = R.id.height_animator_start_value_tag;
     private static final int TAG_START_TOP_INSET = R.id.top_inset_animator_start_value_tag;
+    private static final int TAG_START_SHADOW_ALPHA = R.id.shadow_alpha_animator_start_value_tag;
 
-    private final Interpolator mFastOutSlowInInterpolator;
     private final Interpolator mHeadsUpAppearInterpolator;
     private final int mGoToFullShadeAppearingTranslation;
     private final StackViewState mTmpState = new StackViewState();
@@ -99,8 +97,6 @@
 
     public StackStateAnimator(NotificationStackScrollLayout hostLayout) {
         mHostLayout = hostLayout;
-        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(hostLayout.getContext(),
-                android.R.interpolator.fast_out_slow_in);
         mGoToFullShadeAppearingTranslation =
                 hostLayout.getContext().getResources().getDimensionPixelSize(
                         R.dimen.go_to_full_shade_appearing_translation);
@@ -200,7 +196,6 @@
      */
     public void startStackAnimations(final ExpandableView child, StackViewState viewState,
             StackScrollState finalState, int i, long fixedDelay) {
-        final float alpha = viewState.alpha;
         boolean wasAdded = mNewAddChildren.contains(child);
         long duration = mCurrentLength;
         if (wasAdded && mAnimationFilter.hasGoToFullShadeEvent) {
@@ -212,14 +207,14 @@
         }
         boolean yTranslationChanging = child.getTranslationY() != viewState.yTranslation;
         boolean zTranslationChanging = child.getTranslationZ() != viewState.zTranslation;
-        boolean scaleChanging = child.getScaleX() != viewState.scale;
-        boolean alphaChanging = alpha != child.getAlpha();
+        boolean alphaChanging = viewState.alpha != child.getAlpha();
         boolean heightChanging = viewState.height != child.getActualHeight();
+        boolean shadowAlphaChanging = viewState.shadowAlpha != child.getShadowAlpha();
         boolean darkChanging = viewState.dark != child.isDark();
         boolean topInsetChanging = viewState.clipTopAmount != child.getClipTopAmount();
         boolean hasDelays = mAnimationFilter.hasDelays;
-        boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || scaleChanging ||
-                alphaChanging || heightChanging || topInsetChanging || darkChanging;
+        boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || alphaChanging
+                || heightChanging || topInsetChanging || darkChanging || shadowAlphaChanging;
         long delay = 0;
         if (fixedDelay != -1) {
             delay = fixedDelay;
@@ -234,6 +229,11 @@
             startHeightAnimation(child, viewState, duration, delay);
         }
 
+        // start shadow alpha animation
+        if (shadowAlphaChanging) {
+            startShadowAlphaAnimation(child, viewState, duration, delay);
+        }
+
         // start top inset animation
         if (topInsetChanging) {
             startInsetAnimation(child, viewState, duration, delay);
@@ -255,10 +255,7 @@
         if (wasAdded) {
             child.performAddAnimation(delay, mCurrentLength);
         }
-        if (child instanceof SpeedBumpView) {
-            finalState.performSpeedBumpAnimation(i, (SpeedBumpView) child, viewState,
-                    delay + duration);
-        } else if (child instanceof ExpandableNotificationRow) {
+        if (child instanceof ExpandableNotificationRow) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) child;
             row.startChildAnimation(finalState, this, delay, duration);
         }
@@ -275,13 +272,12 @@
     public void startViewAnimations(View child, ViewState viewState, long delay, long duration) {
         boolean wasVisible = child.getVisibility() == View.VISIBLE;
         final float alpha = viewState.alpha;
-        if (!wasVisible && alpha != 0 && !viewState.gone) {
+        if (!wasVisible && alpha != 0 && !viewState.gone && !viewState.hidden) {
             child.setVisibility(View.VISIBLE);
         }
         boolean yTranslationChanging = child.getTranslationY() != viewState.yTranslation;
         boolean zTranslationChanging = child.getTranslationZ() != viewState.zTranslation;
-        boolean scaleChanging = child.getScaleX() != viewState.scale;
-        float childAlpha = child.getVisibility() == View.INVISIBLE ? 0.0f : child.getAlpha();
+        float childAlpha = child.getAlpha();
         boolean alphaChanging = viewState.alpha != childAlpha;
         if (child instanceof ExpandableView) {
             // We don't want views to change visibility when they are animating to GONE
@@ -298,11 +294,6 @@
             startZTranslationAnimation(child, viewState, duration, delay);
         }
 
-        // start scale animation
-        if (scaleChanging) {
-            startScaleAnimation(child, viewState, duration);
-        }
-
         // start alpha animation
         if (alphaChanging && child.getTranslationX() == 0) {
             startAlphaAnimation(child, viewState, duration, delay);
@@ -384,6 +375,64 @@
         return (long) (index * ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE);
     }
 
+    private void startShadowAlphaAnimation(final ExpandableView child,
+            StackViewState viewState, long duration, long delay) {
+        Float previousStartValue = getChildTag(child, TAG_START_SHADOW_ALPHA);
+        Float previousEndValue = getChildTag(child, TAG_END_SHADOW_ALPHA);
+        float newEndValue = viewState.shadowAlpha;
+        if (previousEndValue != null && previousEndValue == newEndValue) {
+            return;
+        }
+        ValueAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_SHADOW_ALPHA);
+        if (!mAnimationFilter.animateShadowAlpha) {
+            // just a local update was performed
+            if (previousAnimator != null) {
+                // we need to increase all animation keyframes of the previous animator by the
+                // relative change to the end value
+                PropertyValuesHolder[] values = previousAnimator.getValues();
+                float relativeDiff = newEndValue - previousEndValue;
+                float newStartValue = previousStartValue + relativeDiff;
+                values[0].setFloatValues(newStartValue, newEndValue);
+                child.setTag(TAG_START_SHADOW_ALPHA, newStartValue);
+                child.setTag(TAG_END_SHADOW_ALPHA, newEndValue);
+                previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+                return;
+            } else {
+                // no new animation needed, let's just apply the value
+                child.setShadowAlpha(newEndValue);
+                return;
+            }
+        }
+
+        ValueAnimator animator = ValueAnimator.ofFloat(child.getShadowAlpha(), newEndValue);
+        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                child.setShadowAlpha((float) animation.getAnimatedValue());
+            }
+        });
+        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
+        animator.setDuration(newDuration);
+        if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
+            animator.setStartDelay(delay);
+        }
+        animator.addListener(getGlobalAnimationFinishedListener());
+        // remove the tag when the animation is finished
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                child.setTag(TAG_ANIMATOR_SHADOW_ALPHA, null);
+                child.setTag(TAG_START_SHADOW_ALPHA, null);
+                child.setTag(TAG_END_SHADOW_ALPHA, null);
+            }
+        });
+        startAnimator(animator);
+        child.setTag(TAG_ANIMATOR_SHADOW_ALPHA, animator);
+        child.setTag(TAG_START_SHADOW_ALPHA, child.getShadowAlpha());
+        child.setTag(TAG_END_SHADOW_ALPHA, newEndValue);
+    }
+
     private void startHeightAnimation(final ExpandableView child,
             StackViewState viewState, long duration, long delay) {
         Integer previousStartValue = getChildTag(child, TAG_START_HEIGHT);
@@ -421,7 +470,7 @@
                         false /* notifyListeners */);
             }
         });
-        animator.setInterpolator(mFastOutSlowInInterpolator);
+        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
         if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
@@ -479,7 +528,7 @@
                 child.setClipTopAmount((int) animation.getAnimatedValue());
             }
         });
-        animator.setInterpolator(mFastOutSlowInInterpolator);
+        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
         if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
@@ -534,7 +583,7 @@
 
         ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.ALPHA,
                 child.getAlpha(), newEndValue);
-        animator.setInterpolator(mFastOutSlowInInterpolator);
+        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         // Handle layer type
         child.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         animator.addListener(new AnimatorListenerAdapter() {
@@ -605,7 +654,7 @@
 
         ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Z,
                 child.getTranslationZ(), newEndValue);
-        animator.setInterpolator(mFastOutSlowInInterpolator);
+        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
         if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
@@ -659,7 +708,7 @@
         ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Y,
                 child.getTranslationY(), newEndValue);
         Interpolator interpolator = mHeadsUpAppearChildren.contains(child) ?
-                mHeadsUpAppearInterpolator :mFastOutSlowInInterpolator;
+                mHeadsUpAppearInterpolator :Interpolators.FAST_OUT_SLOW_IN;
         animator.setInterpolator(interpolator);
         long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
         animator.setDuration(newDuration);
@@ -683,60 +732,6 @@
         child.setTag(TAG_END_TRANSLATION_Y, newEndValue);
     }
 
-    private void startScaleAnimation(final View child,
-            ViewState viewState, long duration) {
-        Float previousStartValue = getChildTag(child, TAG_START_SCALE);
-        Float previousEndValue = getChildTag(child, TAG_END_SCALE);
-        float newEndValue = viewState.scale;
-        if (previousEndValue != null && previousEndValue == newEndValue) {
-            return;
-        }
-        ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_SCALE);
-        if (!mAnimationFilter.animateScale) {
-            // just a local update was performed
-            if (previousAnimator != null) {
-                // we need to increase all animation keyframes of the previous animator by the
-                // relative change to the end value
-                PropertyValuesHolder[] values = previousAnimator.getValues();
-                float relativeDiff = newEndValue - previousEndValue;
-                float newStartValue = previousStartValue + relativeDiff;
-                values[0].setFloatValues(newStartValue, newEndValue);
-                values[1].setFloatValues(newStartValue, newEndValue);
-                child.setTag(TAG_START_SCALE, newStartValue);
-                child.setTag(TAG_END_SCALE, newEndValue);
-                previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
-                return;
-            } else {
-                // no new animation needed, let's just apply the value
-                child.setScaleX(newEndValue);
-                child.setScaleY(newEndValue);
-            }
-        }
-
-        PropertyValuesHolder holderX =
-                PropertyValuesHolder.ofFloat(View.SCALE_X, child.getScaleX(), newEndValue);
-        PropertyValuesHolder holderY =
-                PropertyValuesHolder.ofFloat(View.SCALE_Y, child.getScaleY(), newEndValue);
-        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(child, holderX, holderY);
-        animator.setInterpolator(mFastOutSlowInInterpolator);
-        long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
-        animator.setDuration(newDuration);
-        animator.addListener(getGlobalAnimationFinishedListener());
-        // remove the tag when the animation is finished
-        animator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                child.setTag(TAG_ANIMATOR_SCALE, null);
-                child.setTag(TAG_START_SCALE, null);
-                child.setTag(TAG_END_SCALE, null);
-            }
-        });
-        startAnimator(animator);
-        child.setTag(TAG_ANIMATOR_SCALE, animator);
-        child.setTag(TAG_START_SCALE, child.getScaleX());
-        child.setTag(TAG_END_SCALE, newEndValue);
-    }
-
     private void startAnimator(ValueAnimator animator) {
         mAnimatorSet.add(animator);
         animator.start();
@@ -934,7 +929,7 @@
                         isRubberbanded);
             }
         });
-        overScrollAnimator.setInterpolator(mFastOutSlowInInterpolator);
+        overScrollAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         overScrollAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -976,6 +971,22 @@
         }
     }
 
+    /**
+     * Get the end value of the height animation running on a view or the actualHeight
+     * if no animation is running.
+     */
+    public static float getFinalTranslationY(ExpandableView view) {
+        if (view == null) {
+            return 0;
+        }
+        ValueAnimator yAnimator = getChildTag(view, TAG_ANIMATOR_TRANSLATION_Y);
+        if (yAnimator == null) {
+            return view.getTranslationY();
+        } else {
+            return getChildTag(view, TAG_END_TRANSLATION_Y);
+        }
+    }
+
     public void setHeadsUpAppearHeightBottom(int headsUpAppearHeightBottom) {
         mHeadsUpAppearHeightBottom = headsUpAppearHeightBottom;
     }
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 55ef440..41824ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackViewState.java
@@ -42,6 +42,7 @@
     public boolean dark;
     public boolean hideSensitive;
     public boolean belowSpeedBump;
+    public float shadowAlpha;
 
     /**
      * The amount which the view should be clipped from the top. This is calculated to
@@ -74,6 +75,7 @@
             StackViewState svs = (StackViewState) viewState;
             height = svs.height;
             dimmed = svs.dimmed;
+            shadowAlpha = svs.shadowAlpha;
             dark = svs.dark;
             hideSensitive = svs.hideSensitive;
             belowSpeedBump = svs.belowSpeedBump;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java
index 3e538df..5beaac3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java
@@ -29,21 +29,21 @@
     public float yTranslation;
     public float zTranslation;
     public boolean gone;
-    public float scale;
+    public boolean hidden;
 
     public void copyFrom(ViewState viewState) {
         alpha = viewState.alpha;
         yTranslation = viewState.yTranslation;
         zTranslation = viewState.zTranslation;
         gone = viewState.gone;
-        scale = viewState.scale;
+        hidden = viewState.hidden;
     }
 
     public void initFrom(View view) {
-        alpha = view.getVisibility() == View.INVISIBLE ? 0.0f : view.getAlpha();
+        alpha = view.getAlpha();
         yTranslation = view.getTranslationY();
         zTranslation = view.getTranslationZ();
         gone = view.getVisibility() == View.GONE;
-        scale = view.getScaleX();
+        hidden = false;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixTile.java b/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixTile.java
index 1fd2352..3206882 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixTile.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ColorMatrixTile.java
@@ -17,7 +17,7 @@
 
 import android.app.ActivityManager;
 import android.provider.Settings;
-import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import libcore.util.Objects;
@@ -102,6 +102,6 @@
 
     @Override
     public int getMetricsCategory() {
-        return MetricsLogger.QS_COLOR_MATRIX;
+        return MetricsEvent.QS_COLOR_MATRIX;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index f1de234..f801963 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -31,6 +31,7 @@
 import android.view.MenuItem;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.DemoMode;
 import com.android.systemui.R;
 
@@ -94,13 +95,13 @@
     @Override
     public void onResume() {
         super.onResume();
-        MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_DEMO_MODE, true);
+        MetricsLogger.visibility(getContext(), MetricsEvent.TUNER_DEMO_MODE, true);
     }
 
     @Override
     public void onPause() {
         super.onPause();
-        MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_DEMO_MODE, false);
+        MetricsLogger.visibility(getContext(), MetricsEvent.TUNER_DEMO_MODE, false);
     }
 
     @Override
@@ -131,10 +132,10 @@
                 mOnSwitch.setChecked(false);
                 stopDemoMode();
             }
-            MetricsLogger.action(getContext(), MetricsLogger.TUNER_DEMO_MODE_ENABLED, enabled);
+            MetricsLogger.action(getContext(), MetricsEvent.TUNER_DEMO_MODE_ENABLED, enabled);
             setGlobal(DemoMode.DEMO_MODE_ALLOWED, enabled ? 1 : 0);
         } else if (preference == mOnSwitch) {
-            MetricsLogger.action(getContext(), MetricsLogger.TUNER_DEMO_MODE_ON, enabled);
+            MetricsLogger.action(getContext(), MetricsEvent.TUNER_DEMO_MODE_ON, enabled);
             if (enabled) {
                 startDemoMode();
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
index 920ec75..f2f0382 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
@@ -24,6 +24,7 @@
 import android.util.AttributeSet;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService.Tunable;
 
@@ -63,14 +64,14 @@
         if (!value) {
             // If not enabled add to blacklist.
             if (!mBlacklist.contains(getKey())) {
-                MetricsLogger.action(getContext(), MetricsLogger.TUNER_STATUS_BAR_DISABLE,
+                MetricsLogger.action(getContext(), MetricsEvent.TUNER_STATUS_BAR_DISABLE,
                         getKey());
                 mBlacklist.add(getKey());
                 setList(mBlacklist);
             }
         } else {
             if (mBlacklist.remove(getKey())) {
-                MetricsLogger.action(getContext(), MetricsLogger.TUNER_STATUS_BAR_ENABLE, getKey());
+                MetricsLogger.action(getContext(), MetricsEvent.TUNER_STATUS_BAR_ENABLE, getKey());
                 setList(mBlacklist);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index a3fe6bb..427b5e8 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -36,6 +36,7 @@
 import android.view.MenuItem;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 
 import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
@@ -84,7 +85,7 @@
         getContext().getContentResolver().registerContentObserver(
                 System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
 
-        MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, true);
+        MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, true);
     }
 
     @Override
@@ -92,7 +93,7 @@
         super.onPause();
         getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
 
-        MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, false);
+        MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, false);
     }
 
     @Override
@@ -141,7 +142,7 @@
         @Override
         public boolean onPreferenceChange(Preference preference, Object newValue) {
             final boolean v = (Boolean) newValue;
-            MetricsLogger.action(getContext(), MetricsLogger.TUNER_BATTERY_PERCENTAGE, v);
+            MetricsLogger.action(getContext(), MetricsEvent.TUNER_BATTERY_PERCENTAGE, v);
             System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0);
             return true;
         }
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 bed1e9e..e947ed5 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -29,7 +29,6 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -38,7 +37,6 @@
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 
-import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 
 /**
@@ -96,6 +94,12 @@
             }
         }
     };
+    private final Runnable mOnPinnedActivityRestartAttempt = new Runnable() {
+        @Override
+        public void run() {
+            movePipToFullscreen();
+        }
+    };
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -314,6 +318,12 @@
             // Post the message back to the UI thread.
             mHandler.post(mOnActivityPinnedRunnable);
         }
+
+        @Override
+        public void onPinnedActivityRestartAttempt() {
+            // Post the message back to the UI thread.
+            mHandler.post(mOnPinnedActivityRestartAttempt);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java
index 893c939..8e0f9b8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Events.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java
@@ -23,6 +23,7 @@
 import android.util.Log;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.volume.VolumeDialogController.State;
 
 import java.util.Arrays;
@@ -111,33 +112,33 @@
             sb.append(" ");
             switch (tag) {
                 case EVENT_SHOW_DIALOG:
-                    MetricsLogger.visible(context, MetricsLogger.VOLUME_DIALOG);
+                    MetricsLogger.visible(context, MetricsEvent.VOLUME_DIALOG);
                     MetricsLogger.histogram(context, "volume_from_keyguard",
                             (Boolean) list[1] ? 1 : 0);
                     sb.append(SHOW_REASONS[(Integer) list[0]]).append(" keyguard=").append(list[1]);
                     break;
                 case EVENT_EXPAND:
-                    MetricsLogger.visibility(context, MetricsLogger.VOLUME_DIALOG_DETAILS,
+                    MetricsLogger.visibility(context, MetricsEvent.VOLUME_DIALOG_DETAILS,
                             (Boolean) list[0]);
                     sb.append(list[0]);
                     break;
                 case EVENT_DISMISS_DIALOG:
-                    MetricsLogger.hidden(context, MetricsLogger.VOLUME_DIALOG);
+                    MetricsLogger.hidden(context, MetricsEvent.VOLUME_DIALOG);
                     sb.append(DISMISS_REASONS[(Integer) list[0]]);
                     break;
                 case EVENT_ACTIVE_STREAM_CHANGED:
-                    MetricsLogger.action(context, MetricsLogger.ACTION_VOLUME_STREAM,
+                    MetricsLogger.action(context, MetricsEvent.ACTION_VOLUME_STREAM,
                             (Integer) list[0]);
                     sb.append(AudioSystem.streamToString((Integer) list[0]));
                     break;
                 case EVENT_ICON_CLICK:
-                    MetricsLogger.action(context, MetricsLogger.ACTION_VOLUME_ICON,
+                    MetricsLogger.action(context, MetricsEvent.ACTION_VOLUME_ICON,
                             (Integer) list[1]);
                     sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ')
                             .append(iconStateToString((Integer) list[1]));
                     break;
                 case EVENT_TOUCH_LEVEL_DONE:
-                    MetricsLogger.action(context, MetricsLogger.ACTION_VOLUME_SLIDER,
+                    MetricsLogger.action(context, MetricsEvent.ACTION_VOLUME_SLIDER,
                             (Integer) list[1]);
                     // fall through
                 case EVENT_TOUCH_LEVEL_CHANGED:
@@ -147,13 +148,13 @@
                             .append(list[1]);
                     break;
                 case EVENT_KEY:
-                    MetricsLogger.action(context, MetricsLogger.ACTION_VOLUME_KEY,
+                    MetricsLogger.action(context, MetricsEvent.ACTION_VOLUME_KEY,
                             (Integer) list[1]);
                     sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ')
                             .append(list[1]);
                     break;
                 case EVENT_EXTERNAL_RINGER_MODE_CHANGED:
-                    MetricsLogger.action(context, MetricsLogger.ACTION_RINGER_MODE,
+                    MetricsLogger.action(context, MetricsEvent.ACTION_RINGER_MODE,
                             (Integer) list[0]);
                     // fall through
                 case EVENT_INTERNAL_RINGER_MODE_CHANGED:
diff --git a/packages/SystemUI/src/com/android/systemui/volume/IconPulser.java b/packages/SystemUI/src/com/android/systemui/volume/IconPulser.java
deleted file mode 100644
index 9438af1..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/IconPulser.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.volume;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.content.Context;
-import android.view.View;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-
-public class IconPulser {
-    private static final float PULSE_SCALE = 1.1f;
-
-    private final Interpolator mFastOutSlowInInterpolator;
-
-    public IconPulser(Context context) {
-        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
-                android.R.interpolator.fast_out_slow_in);
-    }
-
-    public void start(final View target) {
-        if (target == null || target.getScaleX() != 1) return;  // n/a, or already running
-        target.animate().cancel();
-        target.animate().scaleX(PULSE_SCALE).scaleY(PULSE_SCALE)
-                .setInterpolator(mFastOutSlowInInterpolator)
-                .setListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        target.animate().scaleX(1).scaleY(1).setListener(null);
-                    }
-                });
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index ed6fc9e..5dc468b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -254,11 +254,10 @@
         if (D.BUG) Log.d(TAG, "updateWindowWidth dm.w=" + dm.widthPixels);
         int w = dm.widthPixels;
         final int max = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.standard_notification_panel_width);
+                .getDimensionPixelSize(R.dimen.volume_dialog_panel_width);
         if (w > max) {
             w = max;
         }
-        w -= mContext.getResources().getDimensionPixelSize(R.dimen.notification_side_padding) * 2;
         lp.width = w;
         mDialogView.setLayoutParams(lp);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index f73ba6f..e9594a3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -51,6 +51,7 @@
 import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -620,7 +621,7 @@
                         if (childTag == null || childTag == tag) continue;
                         childTag.rb.setChecked(false);
                     }
-                    MetricsLogger.action(mContext, MetricsLogger.QS_DND_CONDITION_SELECT);
+                    MetricsLogger.action(mContext, MetricsEvent.QS_DND_CONDITION_SELECT);
                     select(tag.condition);
                     announceConditionSelection(tag);
                 }
@@ -725,7 +726,7 @@
     }
 
     private void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
-        MetricsLogger.action(mContext, MetricsLogger.QS_DND_TIME, up);
+        MetricsLogger.action(mContext, MetricsEvent.QS_DND_TIME, up);
         Condition newCondition = null;
         final int N = MINUTE_BUCKETS.length;
         if (mBucketIndex == -1) {
@@ -928,7 +929,7 @@
             if (value != null && mZenButtons.isShown() && isAttachedToWindow()) {
                 final int zen = (Integer) value;
                 if (fromClick) {
-                    MetricsLogger.action(mContext, MetricsLogger.QS_DND_ZEN_SELECT, zen);
+                    MetricsLogger.action(mContext, MetricsEvent.QS_DND_ZEN_SELECT, zen);
                 }
                 if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + zen);
                 final Uri realConditionId = getRealConditionId(mSessionExitCondition);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
deleted file mode 100644
index f51e8ff..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import org.mockito.InOrder;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.test.AndroidTestCase;
-
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-
-/** Tests for the data model for the navigation bar app icons. */
-public class NavigationBarAppsModelTest extends AndroidTestCase {
-    private PackageManager mMockPackageManager;
-    private IPackageManager mMockIPackageManager;
-    private SharedPreferences mMockPrefs;
-    private SharedPreferences.Editor mMockEdit;
-    private UserManager mMockUserManager;
-
-    private NavigationBarAppsModel mModel;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        // Mockito setup boilerplate.
-        System.setProperty("dexmaker.dexcache", mContext.getCacheDir().getPath());
-        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-
-        final Context context = mock(Context.class);
-        mMockPackageManager = mock(PackageManager.class);
-        mMockIPackageManager = mock(IPackageManager.class);
-        mMockPrefs = mock(SharedPreferences.class);
-        mMockEdit = mock(SharedPreferences.Editor.class);
-        mMockUserManager = mock(UserManager.class);
-
-        when(context.getSharedPreferences(
-                "com.android.systemui.navbarapps", Context.MODE_PRIVATE)).thenReturn(mMockPrefs);
-        when(context.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
-        when(context.getPackageManager()).thenReturn(mMockPackageManager);
-
-        setContext(context);
-
-        when(mMockUserManager.getUsers()).thenReturn(new ArrayList<UserInfo>());
-        // Assume the version pref is present and equal to the current version.
-        when(mMockPrefs.getInt("version", -1)).thenReturn(3);
-        when(mMockPrefs.edit()).thenReturn(mMockEdit);
-
-        when(mMockUserManager.getSerialNumberForUser(new UserHandle(2))).thenReturn(222L);
-        when(mMockUserManager.getSerialNumberForUser(new UserHandle(4))).thenReturn(444L);
-        when(mMockUserManager.getSerialNumberForUser(new UserHandle(5))).thenReturn(555L);
-        when(mMockUserManager.getUserForSerialNumber(222L)).thenReturn(new UserHandle(2));
-        when(mMockUserManager.getUserForSerialNumber(444L)).thenReturn(new UserHandle(4));
-        when(mMockUserManager.getUserForSerialNumber(555L)).thenReturn(new UserHandle(5));
-
-        UserInfo ui2 = new UserInfo();
-        ui2.profileGroupId = 999;
-        UserInfo ui4 = new UserInfo();
-        ui4.profileGroupId = 999;
-        UserInfo ui5 = new UserInfo();
-        ui5.profileGroupId = 999;
-        when(mMockUserManager.getUserInfo(2)).thenReturn(ui2);
-        when(mMockUserManager.getUserInfo(4)).thenReturn(ui4);
-        when(mMockUserManager.getUserInfo(5)).thenReturn(ui5);
-
-        mModel = new NavigationBarAppsModel(context) {
-            @Override
-            protected IPackageManager getPackageManager() {
-                return mMockIPackageManager;
-            }
-        };
-    }
-
-    /** Tests resolveApp(). */
-    public void testResolveApp() {
-        ActivityInfo mockNonExportedActivityInfo = new ActivityInfo();
-        mockNonExportedActivityInfo.exported = false;
-        ActivityInfo mockExportedActivityInfo = new ActivityInfo();
-        mockExportedActivityInfo.exported = true;
-        try {
-            when(mMockIPackageManager.getActivityInfo(
-                    new ComponentName("package1", "class1"), 0, 4)).
-                    thenReturn(mockNonExportedActivityInfo);
-            when(mMockIPackageManager.getActivityInfo(
-                    new ComponentName("package2", "class2"), 0, 5)).
-                    thenThrow(new RemoteException());
-            when(mMockIPackageManager.getActivityInfo(
-                    new ComponentName("package3", "class3"), 0, 6)).
-                    thenReturn(mockExportedActivityInfo);
-            when(mMockIPackageManager.getActivityInfo(
-                    new ComponentName("package4", "class4"), 0, 7)).
-                    thenReturn(mockExportedActivityInfo);
-        } catch (RemoteException e) {
-            fail("RemoteException can't happen in the test, but it happened.");
-        }
-
-        // Assume some installed activities.
-        ActivityInfo ai0 = new ActivityInfo();
-        ai0.packageName = "package0";
-        ai0.name = "class0";
-        ActivityInfo ai1 = new ActivityInfo();
-        ai1.packageName = "package4";
-        ai1.name = "class4";
-        ResolveInfo ri0 = new ResolveInfo();
-        ri0.activityInfo = ai0;
-        ResolveInfo ri1 = new ResolveInfo();
-        ri1.activityInfo = ai1;
-        when(mMockPackageManager
-                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
-                .thenReturn(Arrays.asList(ri0, ri1));
-
-        mModel.setCurrentUser(3);
-        // Unlauncheable (for various reasons) apps.
-        assertEquals(null, mModel.resolveApp(
-                new AppInfo(new ComponentName("package0", "class0"), new UserHandle(3))));
-        mModel.setCurrentUser(4);
-        assertEquals(null, mModel.resolveApp(
-                new AppInfo(new ComponentName("package1", "class1"), new UserHandle(4))));
-        mModel.setCurrentUser(5);
-        assertEquals(null, mModel.resolveApp(
-                new AppInfo(new ComponentName("package2", "class2"), new UserHandle(5))));
-        mModel.setCurrentUser(6);
-        assertEquals(null, mModel.resolveApp(
-                new AppInfo(new ComponentName("package3", "class3"), new UserHandle(6))));
-
-        // A launcheable app.
-        mModel.setCurrentUser(7);
-        NavigationBarAppsModel.ResolvedApp resolvedApp = mModel.resolveApp(
-                new AppInfo(new ComponentName("package4", "class4"), new UserHandle(7)));
-        assertNotNull(resolvedApp);
-        Intent intent = resolvedApp.launchIntent;
-        assertEquals(new ComponentName("package4", "class4"), intent.getComponent());
-        assertEquals("package4", intent.getPackage());
-        assertEquals(ri1, resolvedApp.ri);
-    }
-
-    /** Initializes the model from SharedPreferences for a few app activites. */
-    private void initializeModelFromPrefs() {
-        // Assume several apps are stored.
-        when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(2);
-        when(mMockPrefs.getString("222|app_0", null)).thenReturn("package1/class1");
-        when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(444L);
-        when(mMockPrefs.getString("222|app_1", null)).thenReturn("package2/class2");
-        when(mMockPrefs.getLong("222|app_user_1", -1)).thenReturn(555L);
-
-        ActivityInfo mockActivityInfo = new ActivityInfo();
-        mockActivityInfo.exported = true;
-        try {
-            when(mMockIPackageManager.getActivityInfo(
-                    new ComponentName("package0", "class0"), 0, 5)).thenReturn(mockActivityInfo);
-            when(mMockIPackageManager.getActivityInfo(
-                    new ComponentName("package1", "class1"), 0, 4)).thenReturn(mockActivityInfo);
-            when(mMockIPackageManager.getActivityInfo(
-                    new ComponentName("package2", "class2"), 0, 5)).thenReturn(mockActivityInfo);
-        } catch (RemoteException e) {
-            fail("RemoteException can't happen in the test, but it happened.");
-        }
-
-        // Assume some installed activities.
-        ActivityInfo ai0 = new ActivityInfo();
-        ai0.packageName = "package0";
-        ai0.name = "class0";
-        ActivityInfo ai1 = new ActivityInfo();
-        ai1.packageName = "package1";
-        ai1.name = "class1";
-        ActivityInfo ai2 = new ActivityInfo();
-        ai2.packageName = "package2";
-        ai2.name = "class2";
-        ResolveInfo ri0 = new ResolveInfo();
-        ri0.activityInfo = ai0;
-        ResolveInfo ri1 = new ResolveInfo();
-        ri1.activityInfo = ai1;
-        ResolveInfo ri2 = new ResolveInfo();
-        ri2.activityInfo = ai2;
-        when(mMockPackageManager
-                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
-                .thenReturn(Arrays.asList(ri0, ri1, ri2));
-
-        mModel.setCurrentUser(2);
-    }
-
-    /** Tests initializing the model from SharedPreferences. */
-    public void testInitializeFromPrefs() {
-        initializeModelFromPrefs();
-        List<AppInfo> apps = mModel.getApps();
-        assertEquals(2, apps.size());
-        assertEquals("package1/class1", apps.get(0).getComponentName().flattenToString());
-        assertEquals(new UserHandle(4), apps.get(0).getUser());
-        assertEquals("package2/class2", apps.get(1).getComponentName().flattenToString());
-        assertEquals(new UserHandle(5), apps.get(1).getUser());
-    }
-
-    /** Tests initializing the model when the SharedPreferences aren't available. */
-    public void testInitializeDefaultApps() {
-        // Assume the user's app count pref isn't available.
-        when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(-1);
-
-        // Assume some installed activities.
-        ActivityInfo ai1 = new ActivityInfo();
-        ai1.packageName = "package1";
-        ai1.name = "class1";
-        ActivityInfo ai2 = new ActivityInfo();
-        ai2.packageName = "package2";
-        ai2.name = "class2";
-        ResolveInfo ri1 = new ResolveInfo();
-        ri1.activityInfo = ai1;
-        ResolveInfo ri2 = new ResolveInfo();
-        ri2.activityInfo = ai2;
-        when(mMockPackageManager
-                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), eq(2)))
-                .thenReturn(Arrays.asList(ri1, ri2));
-
-        // Setting the user should load the installed activities.
-        mModel.setCurrentUser(2);
-        List<AppInfo> apps = mModel.getApps();
-        assertEquals(2, apps.size());
-        assertEquals("package1/class1", apps.get(0).getComponentName().flattenToString());
-        assertEquals(new UserHandle(2), apps.get(0).getUser());
-        assertEquals("package2/class2", apps.get(1).getComponentName().flattenToString());
-        assertEquals(new UserHandle(2), apps.get(1).getUser());
-        InOrder order = inOrder(mMockEdit);
-        order.verify(mMockEdit).apply();
-        order.verify(mMockEdit).putInt("222|app_count", 2);
-        order.verify(mMockEdit).putString("222|app_0", "package1/class1");
-        order.verify(mMockEdit).putLong("222|app_user_0", 222L);
-        order.verify(mMockEdit).putString("222|app_1", "package2/class2");
-        order.verify(mMockEdit).putLong("222|app_user_1", 222L);
-        order.verify(mMockEdit).apply();
-        verifyNoMoreInteractions(mMockEdit);
-    }
-
-    /** Tests initializing the model if one of the prefs is missing. */
-    public void testInitializeWithMissingPref() {
-        // Assume two apps are nominally stored.
-        when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(2);
-        when(mMockPrefs.getString("222|app_0", null)).thenReturn("package0/class0");
-        when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(555L);
-
-        // But assume one pref is missing.
-        when(mMockPrefs.getString("222|app_1", null)).thenReturn(null);
-
-        ActivityInfo mockActivityInfo = new ActivityInfo();
-        mockActivityInfo.exported = true;
-        try {
-            when(mMockIPackageManager.getActivityInfo(
-                    new ComponentName("package0", "class0"), 0, 5)).thenReturn(mockActivityInfo);
-        } catch (RemoteException e) {
-            fail("RemoteException can't happen in the test, but it happened.");
-        }
-
-        ActivityInfo ai0 = new ActivityInfo();
-        ai0.packageName = "package0";
-        ai0.name = "class0";
-        ResolveInfo ri0 = new ResolveInfo();
-        ri0.activityInfo = ai0;
-        when(mMockPackageManager
-                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
-                .thenReturn(Arrays.asList(ri0));
-
-        // Initializing the model should load from prefs and skip the missing one.
-        mModel.setCurrentUser(2);
-        List<AppInfo> apps = mModel.getApps();
-        assertEquals(1, apps.size());
-        assertEquals("package0/class0", apps.get(0).getComponentName().flattenToString());
-        assertEquals(new UserHandle(5), apps.get(0).getUser());
-        InOrder order = inOrder(mMockEdit);
-        order.verify(mMockEdit).putInt("222|app_count", 1);
-        order.verify(mMockEdit).putString("222|app_0", "package0/class0");
-        order.verify(mMockEdit).putLong("222|app_user_0", 555L);
-        order.verify(mMockEdit).apply();
-        verifyNoMoreInteractions(mMockEdit);
-    }
-
-    /** Tests initializing the model if one of the apps is unlauncheable. */
-    public void testInitializeWithUnlauncheableApp() {
-        // Assume two apps are nominally stored.
-        when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(2);
-        when(mMockPrefs.getString("222|app_0", null)).thenReturn("package0/class0");
-        when(mMockPrefs.getLong("222|app_user_0", -1)).thenReturn(555L);
-        when(mMockPrefs.getString("222|app_1", null)).thenReturn("package1/class1");
-        when(mMockPrefs.getLong("222|app_user_1", -1)).thenReturn(444L);
-
-        ActivityInfo mockActivityInfo = new ActivityInfo();
-        mockActivityInfo.exported = true;
-        try {
-            when(mMockIPackageManager.getActivityInfo(
-                    new ComponentName("package0", "class0"), 0, 5)).thenReturn(mockActivityInfo);
-        } catch (RemoteException e) {
-            fail("RemoteException can't happen in the test, but it happened.");
-        }
-
-        ActivityInfo ai0 = new ActivityInfo();
-        ai0.packageName = "package0";
-        ai0.name = "class0";
-        ResolveInfo ri0 = new ResolveInfo();
-        ri0.activityInfo = ai0;
-        when(mMockPackageManager
-                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
-                .thenReturn(Arrays.asList(ri0));
-
-        // Initializing the model should load from prefs and skip the unlauncheable one.
-        mModel.setCurrentUser(2);
-        List<AppInfo> apps = mModel.getApps();
-        assertEquals(1, apps.size());
-        assertEquals("package0/class0", apps.get(0).getComponentName().flattenToString());
-        assertEquals(new UserHandle(5), apps.get(0).getUser());
-
-        // Once an unlauncheable app is detected, the model should save all apps excluding the
-        // unlauncheable one.
-        verify(mMockEdit).putInt("222|app_count", 1);
-        verify(mMockEdit).putString("222|app_0", "package0/class0");
-        verify(mMockEdit).putLong("222|app_user_0", 555L);
-        verify(mMockEdit).apply();
-        verifyNoMoreInteractions(mMockEdit);
-    }
-
-    /** Tests saving the model to SharedPreferences. */
-    public void testSavePrefs() {
-        initializeModelFromPrefs();
-
-        mModel.setApps(mModel.getApps());
-        verify(mMockEdit).putInt("222|app_count", 2);
-        verify(mMockEdit).putString("222|app_0", "package1/class1");
-        verify(mMockEdit).putLong("222|app_user_0", 444L);
-        verify(mMockEdit).putString("222|app_1", "package2/class2");
-        verify(mMockEdit).putLong("222|app_user_1", 555L);
-        verify(mMockEdit).apply();
-        verifyNoMoreInteractions(mMockEdit);
-    }
-
-    /** Tests cleaning all prefs on a version change. */
-    public void testVersionChange() {
-        // Assume the version pref changed.
-        when(mMockPrefs.getInt("version", -1)).thenReturn(1);
-
-        new NavigationBarAppsModel(getContext());
-        verify(mMockEdit).clear();
-        verify(mMockEdit).putInt("version", 3);
-        verify(mMockEdit).apply();
-        verifyNoMoreInteractions(mMockEdit);
-    }
-
-    /** Tests cleaning prefs for deleted users. */
-    public void testCleaningDeletedUsers() {
-        // Users on the device.
-        final UserInfo user1 = new UserInfo(11, "", 0);
-        user1.serialNumber = 1111;
-        final UserInfo user2 = new UserInfo(13, "", 0);
-        user2.serialNumber = 1313;
-
-        when(mMockUserManager.getUsers()).thenReturn(Arrays.asList(user1, user2));
-
-        when(mMockPrefs.edit()).
-                thenReturn(mMockEdit).
-                thenReturn(mock(SharedPreferences.Editor.class));
-
-        // Assume the user's app count pref isn't available. This will trigger clearing deleted
-        // users' prefs.
-        when(mMockPrefs.getInt("222|app_count", -1)).thenReturn(-1);
-
-        final Map allPrefs = new HashMap<String, Object>();
-        allPrefs.put("version", null);
-        allPrefs.put("some_strange_pref", null);
-        allPrefs.put("", null);
-        allPrefs.put("|", null);
-        allPrefs.put("1313|app_count", null);
-        allPrefs.put("1212|app_count", null);
-        when(mMockPrefs.getAll()).thenReturn(allPrefs);
-
-        // Setting the user should remove prefs for deleted users.
-        mModel.setCurrentUser(2);
-        verify(mMockEdit).remove("some_strange_pref");
-        verify(mMockEdit).remove("");
-        verify(mMockEdit).remove("|");
-        verify(mMockEdit).remove("1212|app_count");
-        verify(mMockEdit).apply();
-        verifyNoMoreInteractions(mMockEdit);
-    }
-
-    /** Tests the apps-changed listener. */
-    public void testAppsChangedListeners() {
-        NavigationBarAppsModel.OnAppsChangedListener listener =
-                mock(NavigationBarAppsModel.OnAppsChangedListener.class);
-
-        mModel.addOnAppsChangedListener(listener);
-        mModel.setApps(new ArrayList<AppInfo>());
-        verify(listener).onPinnedAppsChanged();
-        verifyNoMoreInteractions(listener);
-
-        mModel.removeOnAppsChangedListener(listener);
-        mModel.setApps(new ArrayList<AppInfo>());
-        verifyNoMoreInteractions(listener);
-    }
-}
diff --git a/proto/Android.mk b/proto/Android.mk
new file mode 100644
index 0000000..a13a780
--- /dev/null
+++ b/proto/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := framework-protos
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+LOCAL_SRC_FILES:= $(call all-proto-files-under, src)
+LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-oj core-libart
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/jarjar-rules.txt
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/proto/jarjar-rules.txt b/proto/jarjar-rules.txt
new file mode 100644
index 0000000..0c77c2a
--- /dev/null
+++ b/proto/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.google.** com.android.@1
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
new file mode 100644
index 0000000..697777c
--- /dev/null
+++ b/proto/src/metrics_constants.proto
@@ -0,0 +1,346 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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 java_package = "com.android.internal.logging";
+option java_outer_classname = "MetricsProto";
+
+package com_android_internal_logging;
+
+// Wrapper for System UI log events
+message MetricsEvent {
+
+  // Known visual elements: views or controls.
+  enum View {
+    VIEW_UNKNOWN = 0;
+    MAIN_SETTINGS = 1;
+    ACCESSIBILITY = 2;
+    ACCESSIBILITY_CAPTION_PROPERTIES = 3;
+    ACCESSIBILITY_SERVICE = 4;
+    ACCESSIBILITY_TOGGLE_DALTONIZER = 5;
+    ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6;
+    ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7;
+    ACCOUNT = 8;
+    ACCOUNTS_ACCOUNT_SYNC = 9;
+    ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10;
+    ACCOUNTS_MANAGE_ACCOUNTS = 11;
+    APN = 12;
+    APN_EDITOR = 13;
+    APP_OPS_DETAILS = 14;
+    APP_OPS_SUMMARY = 15;
+    APPLICATION = 16;
+    APPLICATIONS_APP_LAUNCH = 17;
+    APPLICATIONS_APP_PERMISSION = 18;
+    APPLICATIONS_APP_STORAGE = 19;
+    APPLICATIONS_INSTALLED_APP_DETAILS = 20;
+    APPLICATIONS_PROCESS_STATS_DETAIL = 21;
+    APPLICATIONS_PROCESS_STATS_MEM_DETAIL = 22;
+    APPLICATIONS_PROCESS_STATS_UI = 23;
+    BLUETOOTH = 24;
+    BLUETOOTH_DEVICE_PICKER = 25;
+    BLUETOOTH_DEVICE_PROFILES = 26;
+    CHOOSE_LOCK_GENERIC = 27;
+    CHOOSE_LOCK_PASSWORD = 28;
+    CHOOSE_LOCK_PATTERN = 29;
+    CONFIRM_LOCK_PASSWORD = 30;
+    CONFIRM_LOCK_PATTERN = 31;
+    CRYPT_KEEPER = 32;
+    CRYPT_KEEPER_CONFIRM = 33;
+    DASHBOARD_SEARCH_RESULTS = 34;
+    DASHBOARD_SUMMARY = 35;
+    DATA_USAGE = 36;
+    DATA_USAGE_SUMMARY = 37;
+    DATE_TIME = 38;
+    DEVELOPMENT = 39;
+    DEVICEINFO = 40;
+    DEVICEINFO_IMEI_INFORMATION = 41;
+    DEVICEINFO_STORAGE = 42;
+    DEVICEINFO_SIM_STATUS = 43;
+    DEVICEINFO_STATUS = 44;
+    DEVICEINFO_USB = 45;
+    DISPLAY = 46;
+    DREAM = 47;
+    ENCRYPTION = 48;
+    FINGERPRINT = 49;
+    FINGERPRINT_ENROLL = 50;
+    FUELGAUGE_BATTERY_HISTORY_DETAIL = 51;
+    FUELGAUGE_BATTERY_SAVER = 52;
+    FUELGAUGE_POWER_USAGE_DETAIL = 53;
+    FUELGAUGE_POWER_USAGE_SUMMARY = 54;
+    HOME = 55;
+    ICC_LOCK = 56;
+    INPUTMETHOD_LANGUAGE = 57;
+    INPUTMETHOD_KEYBOARD = 58;
+    INPUTMETHOD_SPELL_CHECKERS = 59;
+    INPUTMETHOD_SUBTYPE_ENABLER = 60;
+    INPUTMETHOD_USER_DICTIONARY = 61;
+    INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62;
+    LOCATION = 63;
+    LOCATION_MODE = 64;
+    MANAGE_APPLICATIONS = 65;
+    MASTER_CLEAR = 66;
+    MASTER_CLEAR_CONFIRM = 67;
+    NET_DATA_USAGE_METERED = 68;
+    NFC_BEAM = 69;
+    NFC_PAYMENT = 70;
+    NOTIFICATION = 71;
+    NOTIFICATION_APP_NOTIFICATION = 72;
+    NOTIFICATION_OTHER_SOUND = 73;
+    NOTIFICATION_REDACTION = 74;
+    NOTIFICATION_STATION = 75;
+    NOTIFICATION_ZEN_MODE = 76;
+    OWNER_INFO = 77;
+    PRINT_JOB_SETTINGS = 78;
+    PRINT_SERVICE_SETTINGS = 79;
+    PRINT_SETTINGS = 80;
+    PRIVACY = 81;
+    PROXY_SELECTOR = 82;
+    RESET_NETWORK = 83;
+    RESET_NETWORK_CONFIRM = 84;
+    RUNNING_SERVICE_DETAILS = 85;
+    SCREEN_PINNING = 86;
+    SECURITY = 87;
+    SIM = 88;
+    TESTING = 89;
+    TETHER = 90;
+    TRUST_AGENT = 91;
+    TRUSTED_CREDENTIALS = 92;
+    TTS_ENGINE_SETTINGS = 93;
+    TTS_TEXT_TO_SPEECH = 94;
+    USAGE_ACCESS = 95;
+    USER = 96;
+    USERS_APP_RESTRICTIONS = 97;
+    USER_DETAILS = 98;
+    VOICE_INPUT = 99;
+    VPN = 100;
+    WALLPAPER_TYPE = 101;
+    WFD_WIFI_DISPLAY = 102;
+    WIFI = 103;
+    WIFI_ADVANCED = 104;
+    WIFI_CALLING = 105;
+    WIFI_SAVED_ACCESS_POINTS = 106;
+    WIFI_APITEST = 107;
+    WIFI_INFO = 108;
+    WIFI_P2P = 109;
+    WIRELESS = 110;
+    QS_PANEL = 111;
+    QS_AIRPLANEMODE = 112;
+    QS_BLUETOOTH = 113;
+    QS_CAST = 114;
+    QS_CELLULAR = 115;
+    QS_COLORINVERSION = 116;
+    QS_DATAUSAGEDETAIL = 117;
+    QS_DND = 118;
+    QS_FLASHLIGHT = 119;
+    QS_HOTSPOT = 120;
+    QS_INTENT = 121;
+    QS_LOCATION = 122;
+    QS_ROTATIONLOCK = 123;
+    QS_USERDETAILITE = 124;
+    QS_USERDETAIL = 125;
+    QS_WIFI = 126;
+    NOTIFICATION_PANEL = 127;
+    NOTIFICATION_ITEM = 128;
+    NOTIFICATION_ITEM_ACTION = 129;
+    APPLICATIONS_ADVANCED = 130;
+    LOCATION_SCANNING = 131;
+    MANAGE_APPLICATIONS_ALL = 132;
+    MANAGE_APPLICATIONS_NOTIFICATIONS = 133;
+    ACTION_WIFI_ADD_NETWORK = 134;
+    ACTION_WIFI_CONNECT = 135;
+    ACTION_WIFI_FORCE_SCAN = 136;
+    ACTION_WIFI_FORGET = 137;
+    ACTION_WIFI_OFF = 138;
+    ACTION_WIFI_ON = 139;
+    MANAGE_PERMISSIONS = 140;
+    NOTIFICATION_ZEN_MODE_PRIORITY = 141;
+    NOTIFICATION_ZEN_MODE_AUTOMATION = 142;
+    MANAGE_DOMAIN_URLS = 143;
+    NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
+    NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145;
+    NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
+    ACTION_BAN_APP_NOTES = 147;
+    ACTION_DISMISS_ALL_NOTES = 148;
+    QS_DND_DETAILS = 149;
+    QS_BLUETOOTH_DETAILS = 150;
+    QS_CAST_DETAILS = 151;
+    QS_WIFI_DETAILS = 152;
+    QS_WIFI_TOGGLE = 153;
+    QS_BLUETOOTH_TOGGLE = 154;
+    QS_CELLULAR_TOGGLE = 155;
+    QS_SWITCH_USER = 156;
+    QS_CAST_SELECT = 157;
+    QS_CAST_DISCONNECT = 158;
+    ACTION_BLUETOOTH_TOGGLE = 159;
+    ACTION_BLUETOOTH_SCAN = 160;
+    ACTION_BLUETOOTH_RENAME = 161;
+    ACTION_BLUETOOTH_FILES = 162;
+    QS_DND_TIME = 163;
+    QS_DND_CONDITION_SELECT = 164;
+    QS_DND_ZEN_SELECT = 165;
+    QS_DND_TOGGLE = 166;
+    ACTION_ZEN_ALLOW_REMINDERS = 167;
+    ACTION_ZEN_ALLOW_EVENTS = 168;
+    ACTION_ZEN_ALLOW_MESSAGES = 169;
+    ACTION_ZEN_ALLOW_CALLS = 170;
+    ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
+    ACTION_ZEN_ADD_RULE = 172;
+    ACTION_ZEN_ADD_RULE_OK = 173;
+    ACTION_ZEN_DELETE_RULE = 174;
+    ACTION_ZEN_DELETE_RULE_OK = 175;
+    ACTION_ZEN_ENABLE_RULE = 176;
+    ACTION_AIRPLANE_TOGGLE = 177;
+    ACTION_CELL_DATA_TOGGLE = 178;
+    NOTIFICATION_ACCESS = 179;
+    NOTIFICATION_ZEN_MODE_ACCESS = 180;
+    APPLICATIONS_DEFAULT_APPS = 181;
+    APPLICATIONS_STORAGE_APPS = 182;
+    APPLICATIONS_USAGE_ACCESS_DETAIL = 183;
+    APPLICATIONS_HIGH_POWER_APPS = 184;
+    FUELGAUGE_HIGH_POWER_DETAILS = 185;
+    ACTION_LS_UNLOCK = 186;
+    ACTION_LS_SHADE = 187;
+    ACTION_LS_HINT = 188;
+    ACTION_LS_CAMERA = 189;
+    ACTION_LS_DIALER = 190;
+    ACTION_LS_LOCK = 191;
+    ACTION_LS_NOTE = 192;
+    ACTION_LS_QS = 193;
+    ACTION_SHADE_QS_PULL = 194;
+    ACTION_SHADE_QS_TAP = 195;
+    LOCKSCREEN = 196;
+    BOUNCER = 197;
+    SCREEN = 198;
+    NOTIFICATION_ALERT = 199;
+    ACTION_EMERGENCY_CALL = 200;
+    APPLICATIONS_MANAGE_ASSIST = 201;
+    PROCESS_STATS_SUMMARY = 202;
+    ACTION_ROTATION_LOCK = 203;
+    ACTION_NOTE_CONTROLS = 204;
+    ACTION_NOTE_INFO = 205;
+    ACTION_APP_NOTE_SETTINGS = 206;
+    VOLUME_DIALOG = 207;
+    VOLUME_DIALOG_DETAILS = 208;
+    ACTION_VOLUME_SLIDER = 209;
+    ACTION_VOLUME_STREAM = 210;
+    ACTION_VOLUME_KEY = 211;
+    ACTION_VOLUME_ICON = 212;
+    ACTION_RINGER_MODE = 213;
+    ACTION_ACTIVITY_CHOOSER_SHOWN = 214;
+    ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET = 215;
+    ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET = 216;
+    ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET = 217;
+    ACTION_BRIGHTNESS = 218;
+    ACTION_BRIGHTNESS_AUTO = 219;
+    BRIGHTNESS_DIALOG = 220;
+    SYSTEM_ALERT_WINDOW_APPS = 221;
+    DREAMING = 222;
+    DOZING = 223;
+    OVERVIEW_ACTIVITY = 224;
+    ABOUT_LEGAL_SETTINGS = 225;
+    ACTION_SEARCH_RESULTS = 226;
+    TUNER = 227;
+    TUNER_QS = 228;
+    TUNER_DEMO_MODE = 229;
+    TUNER_QS_REORDER = 230;
+    TUNER_QS_ADD = 231;
+    TUNER_QS_REMOVE = 232;
+    TUNER_STATUS_BAR_ENABLE = 233;
+    TUNER_STATUS_BAR_DISABLE = 234;
+    TUNER_DEMO_MODE_ENABLED = 235;
+    TUNER_DEMO_MODE_ON = 236;
+    TUNER_BATTERY_PERCENTAGE = 237;
+    FUELGAUGE_INACTIVE_APPS = 238;
+    ACTION_ASSIST_LONG_PRESS = 239;
+    FINGERPRINT_ENROLLING = 240;
+    FINGERPRINT_FIND_SENSOR = 241;
+    FINGERPRINT_ENROLL_FINISH = 242;
+    FINGERPRINT_ENROLL_INTRO = 243;
+    FINGERPRINT_ENROLL_ONBOARD = 244;
+    FINGERPRINT_ENROLL_SIDECAR = 245;
+    FINGERPRINT_ENROLLING_SETUP = 246;
+    FINGERPRINT_FIND_SENSOR_SETUP = 247;
+    FINGERPRINT_ENROLL_FINISH_SETUP = 248;
+    FINGERPRINT_ENROLL_INTRO_SETUP = 249;
+    FINGERPRINT_ENROLL_ONBOARD_SETUP = 250;
+    ACTION_FINGERPRINT_ENROLL = 251;
+    ACTION_FINGERPRINT_AUTH = 252;
+    ACTION_FINGERPRINT_DELETE = 253;
+    ACTION_FINGERPRINT_RENAME = 254;
+    ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE = 255;
+    ACTION_WIGGLE_CAMERA_GESTURE = 256;
+    QS_WORKMODE = 257;
+    BACKGROUND_CHECK_SUMMARY = 258;
+    QS_LOCK_TILE = 259;
+    QS_USER_TILE = 260;
+    QS_BATTERY_TILE = 261;
+    NOTIFICATION_ZEN_MODE_VISUAL_INTERRUPTIONS = 262;
+    ACTION_ZEN_ALLOW_PEEK = 263;
+    ACTION_ZEN_ALLOW_LIGHTS = 264;
+    NOTIFICATION_TOPIC_NOTIFICATION = 265;
+    ACTION_DEFAULT_SMS_APP_CHANGED = 266;
+    QS_COLOR_MATRIX = 267;
+    QS_CUSTOM = 268;
+    ACTION_ZEN_ALLOW_SCREEN_ON = 269;
+
+    // Logged when the user docks a window from recents by
+    // longpressing a task and dragging it to the dock area.
+    ACTION_WINDOW_DOCK_DRAG_DROP = 270;
+
+    // Logged when the user docks a fullscreen window by long pressing
+    // recents which also opens recents on the lower/right side.
+    ACTION_WINDOW_DOCK_LONGPRESS = 271;
+
+    // Logged when the user docks a window by dragging from the navbar
+    // which also opens recents on the lower/right side.
+    ACTION_WINDOW_DOCK_SWIPE = 272;
+
+    // Logged when the user launches a profile-specific app and we
+    // intercept it with the confirm credentials UI.
+    PROFILE_CHALLENGE = 273;
+
+    QS_BATTERY_DETAIL = 274;
+
+    // Logged when the user goes into the overview history.
+    OVERVIEW_HISTORY = 275;
+
+    // Logged when the user pages through overview.
+    ACTION_OVERVIEW_PAGE = 276;
+
+    // Logged when the user launches a task from overview.
+    ACTION_OVERVIEW_SELECT = 277;
+
+    // Logged when the user views the emergency info.
+    ACTION_VIEW_EMERGENCY_INFO = 278;
+
+    // Logged when the user views the edit emergency info activity.
+    ACTION_EDIT_EMERGENCY_INFO = 279;
+
+    // Logged when the user edits an emergency info field.
+    ACTION_EDIT_EMERGENCY_INFO_FIELD = 280;
+
+    // Logged when the user adds a new emergency contact.
+    ACTION_ADD_EMERGENCY_CONTACT = 281;
+
+    // Logged when the user deletes an emergency contact.
+    ACTION_DELETE_EMERGENCY_CONTACT = 282;
+
+    // Logged when the user calls an emergency contact.
+    ACTION_CALL_EMERGENCY_CONTACT = 283;
+
+    // QS Tile for Data Saver.
+    QS_DATA_SAVER = 284;
+  }
+}
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index a4876b9..a71ba636 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -16,14 +16,16 @@
 
 package android.renderscript;
 
+import java.nio.ByteBuffer;
 import java.util.HashMap;
+
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.view.Surface;
-import android.util.Log;
 import android.graphics.Canvas;
 import android.os.Trace;
+import android.util.Log;
+import android.view.Surface;
 
 /**
  * <p> This class provides the primary method through which data is passed to
@@ -78,6 +80,8 @@
     OnBufferAvailableListener mBufferNotifier;
 
     private Surface mGetSurfaceSurface = null;
+    private ByteBuffer mByteBuffer = null;
+    private long mByteBufferStride = -1;
 
     private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) {
         final Class c = d.getClass();
@@ -2050,6 +2054,59 @@
     }
 
     /**
+     * @hide
+     * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
+     * If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
+     * would contain the up-to-date data as READ ONLY.
+     * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
+     * the Allocation has certain alignment. The size of each row including padding,
+     * called stride, can be queried using the {@link #getStride()} method.
+     *
+     * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
+     *
+     * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
+     */
+    public ByteBuffer getByteBuffer() {
+        // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
+        if (mType.hasFaces()) {
+            throw new RSInvalidStateException("Cubemap is not supported for getByteBuffer().");
+        }
+        if (mType.getYuv() == android.graphics.ImageFormat.NV21 ||
+            mType.getYuv() == android.graphics.ImageFormat.YV12 ||
+            mType.getYuv() == android.graphics.ImageFormat.YUV_420_888 ) {
+            throw new RSInvalidStateException("YUV format is not supported for getByteBuffer().");
+        }
+        if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
+            int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
+            long[] stride = new long[1];
+            mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), stride, xBytesSize, mType.getY(), mType.getZ());
+            mByteBufferStride = stride[0];
+        }
+        if ((mUsage & USAGE_IO_INPUT) != 0) {
+            return mByteBuffer.asReadOnlyBuffer();
+        }
+        return mByteBuffer;
+    }
+
+    /**
+     * @hide
+     * Gets the stride of the Allocation.
+     * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
+     * the Allocation has certain alignment. The size of each row including such
+     * padding is called stride.
+     *
+     * @return the stride. For 1D Allocation, the stride will be the number of
+     *         bytes of this Allocation. For 2D and 3D Allocations, the stride
+     *         will be the stride in X dimension measuring in bytes.
+     */
+    public long getStride() {
+        if (mByteBufferStride == -1) {
+            getByteBuffer();
+        }
+        return mByteBufferStride;
+    }
+
+    /**
      * Returns the handle to a raw buffer that is being managed by the screen
      * compositor. This operation is only valid for Allocations with {@link
      * #USAGE_IO_INPUT}.
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 3668ddd..4788223 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -18,17 +18,18 @@
 
 import java.io.File;
 import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import android.content.Context;
 import android.content.res.AssetManager;
 import android.graphics.Bitmap;
 import android.graphics.SurfaceTexture;
-import android.util.Log;
-import android.view.Surface;
 import android.os.SystemProperties;
 import android.os.Trace;
-import java.util.ArrayList;
+import android.util.Log;
+import android.view.Surface;
 
 // TODO: Clean up the whitespace that separates methods in this class.
 
@@ -489,6 +490,13 @@
         validate();
         rsnAllocationSyncAll(mContext, alloc, src);
     }
+
+    native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, long[] stride, int xBytesSize, int dimY, int dimZ);
+    synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, long[] stride, int xBytesSize, int dimY, int dimZ) {
+        validate();
+        return rsnAllocationGetByteBuffer(mContext, alloc, stride, xBytesSize, dimY, dimZ);
+    }
+
     native Surface rsnAllocationGetSurface(long con, long alloc);
     synchronized Surface nAllocationGetSurface(long alloc) {
         validate();
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index 84f980d..2b06780 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -315,7 +315,6 @@
     /**
      * Only intended for use by generated reflected code.  (General reduction)
      *
-     * @hide
      */
     protected void reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc) {
         mRS.validate();
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 3954070..398d89b 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -2752,7 +2752,43 @@
     return (jint)sizeof(void*);
 }
 
+static jobject
+nAllocationGetByteBuffer(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
+                        jlongArray strideArr, jint xBytesSize,
+                        jint dimY, jint dimZ) {
+    if (kLogApi) {
+        ALOGD("nAllocationGetByteBuffer, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
+    }
 
+    jlong *jStridePtr = _env->GetLongArrayElements(strideArr, nullptr);
+    if (jStridePtr == nullptr) {
+        ALOGE("Failed to get Java array elements: strideArr");
+        return 0;
+    }
+
+    size_t strideIn = xBytesSize;
+    void* ptr = nullptr;
+    if (alloc != 0) {
+        ptr = rsAllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
+                                     RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
+                                     &strideIn, sizeof(size_t));
+    }
+
+    jobject byteBuffer = nullptr;
+    if (ptr != nullptr) {
+        size_t bufferSize = strideIn;
+        jStridePtr[0] = strideIn;
+        if (dimY > 0) {
+            bufferSize *= dimY;
+        }
+        if (dimZ > 0) {
+            bufferSize *= dimZ;
+        }
+        byteBuffer = _env->NewDirectByteBuffer(ptr, (jlong) bufferSize);
+    }
+    _env->ReleaseLongArrayElements(strideArr, jStridePtr, 0);
+    return byteBuffer;
+}
 // ---------------------------------------------------------------------------
 
 
@@ -2909,6 +2945,7 @@
 {"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
 
 {"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
+{"rsnAllocationGetByteBuffer",       "(JJ[JIII)Ljava/nio/ByteBuffer;",        (void*)nAllocationGetByteBuffer },
 };
 
 static int registerFuncs(JNIEnv *_env)
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index dbbb189..03809c0 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1204,8 +1204,13 @@
             }
             builder.append(componentName.flattenToShortString());
         }
-        Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                settingName, builder.toString(), userId);
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                    settingName, builder.toString(), userId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
     }
 
     private void manageServicesLocked(UserState userState) {
@@ -1250,8 +1255,13 @@
         if (isEnabled && userState.mBoundServices.isEmpty()
                 && userState.mBindingServices.isEmpty()) {
             userState.mIsAccessibilityEnabled = false;
-            Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId);
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
         }
     }
 
@@ -1342,9 +1352,14 @@
                          // Enable touch exploration.
                          UserState userState = getUserStateLocked(service.mUserId);
                          userState.mIsTouchExplorationEnabled = true;
-                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                                 Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1,
-                                 service.mUserId);
+                         final long identity = Binder.clearCallingIdentity();
+                         try {
+                             Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                                     Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1,
+                                     service.mUserId);
+                         } finally {
+                             Binder.restoreCallingIdentity(identity);
+                         }
                          onUserStateChangedLocked(userState);
                      }
                  })
@@ -1613,9 +1628,14 @@
         }
         if (enabled != userState.mIsTouchExplorationEnabled) {
             userState.mIsTouchExplorationEnabled = enabled;
-            Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.TOUCH_EXPLORATION_ENABLED, enabled ? 1 : 0,
-                    userState.mUserId);
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.TOUCH_EXPLORATION_ENABLED, enabled ? 1 : 0,
+                        userState.mUserId);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
         }
     }
 
@@ -1666,9 +1686,14 @@
         }
         if (enabled != userState.mIsEnhancedWebAccessibilityEnabled) {
             userState.mIsEnhancedWebAccessibilityEnabled = enabled;
-            Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, enabled ? 1 : 0,
-                    userState.mUserId);
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, enabled ? 1 : 0,
+                        userState.mUserId);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
         }
     }
 
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index d63dd0c..0513e53 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -1920,7 +1920,9 @@
                 synchronized (mBackupParticipants) {
                     if (replacing) {
                         // This is the package-replaced case; we just remove the entry
-                        // under the old uid and fall through to re-add.
+                        // under the old uid and fall through to re-add.  If an app
+                        // just added key/value backup participation, this picks it up
+                        // as a known participant.
                         removePackageParticipantsLocked(pkgList, uid);
                     }
                     addPackageParticipantsLocked(pkgList);
@@ -1933,6 +1935,14 @@
                         if (appGetsFullBackup(app) && appIsEligibleForBackup(app.applicationInfo)) {
                             enqueueFullBackup(packageName, now);
                             scheduleNextFullBackupJob(0);
+                        } else {
+                            // The app might have just transitioned out of full-data into
+                            // doing key/value backups, or might have just disabled backups
+                            // entirely.  Make sure it is no longer in the full-data queue.
+                            synchronized (mQueueLock) {
+                                dequeueFullBackupLocked(packageName);
+                            }
+                            writeFullBackupScheduleAsync();
                         }
 
                         // Transport maintenance: rebind to known existing transports that have
@@ -1964,6 +1974,9 @@
                 if (replacing) {
                     // The package is being updated.  We'll receive a PACKAGE_ADDED shortly.
                 } else {
+                    // Outright removal.  In the full-data case, the app will be dropped
+                    // from the queue when its (now obsolete) name comes up again for
+                    // backup.
                     synchronized (mBackupParticipants) {
                         removePackageParticipantsLocked(pkgList, uid);
                     }
@@ -3155,8 +3168,9 @@
 
             ParcelFileDescriptor backupData = null;
             mStatus = BackupTransport.TRANSPORT_OK;
+            long size = 0;
             try {
-                int size = (int) mBackupDataName.length();
+                size = mBackupDataName.length();
                 if (size > 0) {
                     if (mStatus == BackupTransport.TRANSPORT_OK) {
                         backupData = ParcelFileDescriptor.open(mBackupDataName,
@@ -3201,6 +3215,10 @@
                     sendBackupOnResult(mObserver, pkgName,
                             BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
                     EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
+                } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                    sendBackupOnResult(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);
@@ -3221,6 +3239,20 @@
                 // Success or single-package rejection.  Proceed with the next app if any,
                 // otherwise we're done.
                 nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
+            } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Package " + mCurrentPackage.packageName +
+                            " hit quota limit on k/v backup");
+                }
+                if (mAgentBinder != null) {
+                    try {
+                        long quota = mTransport.getBackupQuota(mCurrentPackage.packageName, false);
+                        mAgentBinder.doQuotaExceeded(size, quota);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Unable to contact backup agent for quota exceeded");
+                    }
+                }
+                nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
             } else {
                 // Any other error here indicates a transport-level failure.  That means
                 // we need to halt everything and reschedule everything for next time.
@@ -3463,6 +3495,7 @@
         OutputStream mOutput;
         FullBackupPreflight mPreflightHook;
         IFullBackupRestoreObserver mObserver;
+        IBackupAgent mAgent;
         File mFilesDir;
         File mManifestFile;
         File mMetadataFile;
@@ -3549,14 +3582,14 @@
             int result = BackupTransport.TRANSPORT_OK;
             Slog.d(TAG, "Binding to full backup agent : " + pkg.packageName);
 
-            IBackupAgent agent = bindToAgentSynchronous(pkg.applicationInfo,
+            mAgent = bindToAgentSynchronous(pkg.applicationInfo,
                     IApplicationThread.BACKUP_MODE_FULL);
-            if (agent != null) {
+            if (mAgent != null) {
                 ParcelFileDescriptor[] pipes = null;
                 try {
                     // Call the preflight hook, if any
                     if (mPreflightHook != null) {
-                        result = mPreflightHook.preflightFullBackup(pkg, agent);
+                        result = mPreflightHook.preflightFullBackup(pkg, mAgent);
                         if (MORE_DEBUG) {
                             Slog.v(TAG, "preflight returned " + result);
                         }
@@ -3579,7 +3612,7 @@
                                 UserHandle.USER_SYSTEM);
 
                         final int token = generateToken();
-                        FullBackupRunner runner = new FullBackupRunner(pkg, agent, pipes[1],
+                        FullBackupRunner runner = new FullBackupRunner(pkg, mAgent, pipes[1],
                                 token, sendApk, !isSharedStorage, widgetBlob);
                         pipes[1].close();   // the runner has dup'd it
                         pipes[1] = null;
@@ -3627,6 +3660,16 @@
             return result;
         }
 
+        public void sendQuotaExceeded(final long backupDataBytes, final long quotaBytes) {
+            if (mAgent != null) {
+                try {
+                    mAgent.doQuotaExceeded(backupDataBytes, quotaBytes);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Remote exception while telling agent about quota exceeded");
+                }
+            }
+        }
+
         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
@@ -4190,11 +4233,21 @@
                         // as well as any explicit mention of the 'special' shared-storage agent
                         // package (we handle that one at the end).
                         if (MORE_DEBUG) {
-                            Slog.d(TAG, "Ignoring not eligible package " + pkg);
+                            Slog.d(TAG, "Ignoring ineligible package " + pkg);
                         }
                         sendBackupOnResult(mBackupObserver, pkg,
                             BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                         continue;
+                    } else if (!appGetsFullBackup(info)) {
+                        // Cull any packages that are found in the queue but now aren't supposed
+                        // to get full-data backup operations.
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "Ignoring full-data backup of key/value participant "
+                                    + pkg);
+                        }
+                        sendBackupOnResult(mBackupObserver, pkg,
+                                BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                        continue;
                     } else if (appIsStopped(info.applicationInfo)) {
                         // Cull any packages in the 'stopped' state: they've either just been
                         // installed or have explicitly been force-stopped by the user.  In both
@@ -4321,6 +4374,15 @@
                             }
                         } while (nRead > 0 && result == 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
+                                        + ": " + totalRead + " of " + 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.
@@ -4364,6 +4426,8 @@
                     }
 
                     if (result == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+                            BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
                         if (DEBUG) {
                             Slog.i(TAG, "Transport rejected backup of "
                                     + currentPackage.packageName
@@ -4371,35 +4435,40 @@
                         }
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE,
                                 currentPackage.packageName, "transport rejected");
-                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
-                            BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
                         // do nothing, clean up, and continue looping
+                    } else if (result == BackupTransport.TRANSPORT_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) {
-                        Slog.w(TAG, "Transport failed; aborting backup: " + result);
-                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
                         sendBackupOnResult(mBackupObserver, currentPackage.packageName,
                             BackupManager.ERROR_TRANSPORT_ABORTED);
+                        Slog.w(TAG, "Transport failed; aborting backup: " + result);
+                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
                         return;
                     } else {
                         // Success!
+                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+                            BackupManager.SUCCESS);
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS,
                                 currentPackage.packageName);
                         logBackupComplete(currentPackage.packageName);
-                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
-                            BackupManager.SUCCESS);
                     }
                     cleanUpPipes(transportPipes);
                     cleanUpPipes(enginePipes);
                     currentPackage = null;
                 }
 
+                sendBackupFinished(mBackupObserver, BackupManager.SUCCESS);
                 if (DEBUG) {
                     Slog.i(TAG, "Full backup completed.");
                 }
-                sendBackupFinished(mBackupObserver, BackupManager.SUCCESS);
             } catch (Exception e) {
-                Slog.w(TAG, "Exception trying full transport backup", e);
                 sendBackupFinished(mBackupObserver, BackupManager.ERROR_TRANSPORT_ABORTED);
+                Slog.w(TAG, "Exception trying full transport backup", e);
             } finally {
                 cleanUpPipes(transportPipes);
                 cleanUpPipes(enginePipes);
@@ -4480,6 +4549,14 @@
                     }
 
                     result = mTransport.checkFullBackupSize(totalSize);
+                    if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                        final long quota = mTransport.getBackupQuota(pkg.packageName, true);
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "Package hit quota limit on preflight " +
+                                    pkg.packageName + ": " + totalSize + " of " + quota);
+                        }
+                        agent.doQuotaExceeded(totalSize, quota);
+                    }
                 } catch (Exception e) {
                     Slog.w(TAG, "Exception preflighting " + pkg.packageName + ": " + e.getMessage());
                     result = BackupTransport.AGENT_ERROR;
@@ -4527,6 +4604,7 @@
             final PackageInfo mTarget;
             final FullBackupPreflight mPreflight;
             final CountDownLatch mLatch;
+            private FullBackupEngine mEngine;
 
             SinglePackageBackupRunner(ParcelFileDescriptor output, PackageInfo target,
                     IBackupTransport transport, CountDownLatch latch) throws IOException {
@@ -4540,9 +4618,9 @@
             public void run() {
                 try {
                     FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
-                    FullBackupEngine engine = new FullBackupEngine(out, mTarget.packageName,
+                    mEngine = new FullBackupEngine(out, mTarget.packageName,
                             mPreflight, false);
-                    engine.backupOnePackage(mTarget);
+                    mEngine.backupOnePackage(mTarget);
                 } catch (Exception e) {
                     Slog.e(TAG, "Exception during full package backup of " + mTarget);
                 } finally {
@@ -4555,6 +4633,10 @@
                 }
             }
 
+            public void sendQuotaExceeded(final long backupDataBytes, final long quotaBytes) {
+                mEngine.sendQuotaExceeded(backupDataBytes, quotaBytes);
+            }
+
             long expectedSize() {
                 return mPreflight.expectedSize();
             }
@@ -4592,21 +4674,28 @@
     }
 
     /**
+     * Remove a package from the full-data queue.
+     */
+    void dequeueFullBackupLocked(String packageName) {
+        final int N = mFullBackupQueue.size();
+        for (int i = N-1; i >= 0; i--) {
+            final FullBackupEntry e = mFullBackupQueue.get(i);
+            if (packageName.equals(e.packageName)) {
+                mFullBackupQueue.remove(i);
+            }
+        }
+    }
+
+    /**
      * Enqueue full backup for the given app, with a note about when it last ran.
      */
     void enqueueFullBackup(String packageName, long lastBackedUp) {
         FullBackupEntry newEntry = new FullBackupEntry(packageName, lastBackedUp);
         synchronized (mQueueLock) {
-            int N = mFullBackupQueue.size();
             // First, sanity check that we aren't adding a duplicate.  Slow but
             // straightforward; we'll have at most on the order of a few hundred
             // items in this list.
-            for (int i = N-1; i >= 0; i--) {
-                final FullBackupEntry e = mFullBackupQueue.get(i);
-                if (packageName.equals(e.packageName)) {
-                    mFullBackupQueue.remove(i);
-                }
-            }
+            dequeueFullBackupLocked(packageName);
 
             // This is also slow but easy for modest numbers of apps: work backwards
             // from the end of the queue until we find an item whose last backup
@@ -4700,21 +4789,24 @@
                 return false;
             }
 
-            if (mFullBackupQueue.size() == 0) {
-                // no work to do so just bow out
-                if (DEBUG) {
-                    Slog.i(TAG, "Backup queue empty; doing nothing");
-                }
-                return false;
-            }
-
-            // At this point we know that we have work to do, but possibly not right now.
+            // At this point we think that we have work to do, but possibly not right now.
             // Any exit without actually running backups will also require that we
             // reschedule the job.
             boolean runBackup = true;
             boolean headBusy;
 
             do {
+                // Recheck each time, because culling due to ineligibility may
+                // have emptied the queue.
+                if (mFullBackupQueue.size() == 0) {
+                    // no work to do so just bow out
+                    if (DEBUG) {
+                        Slog.i(TAG, "Backup queue empty; doing nothing");
+                    }
+                    runBackup = false;
+                    break;
+                }
+
                 headBusy = false;
 
                 if (!fullBackupAllowable(getTransport(mCurrentTransport))) {
@@ -4744,6 +4836,19 @@
 
                     try {
                         PackageInfo appInfo = mPackageManager.getPackageInfo(entry.packageName, 0);
+                        if (!appGetsFullBackup(appInfo)) {
+                            // The head app isn't supposed to get full-data backups [any more];
+                            // so we cull it and force a loop around to consider the new head
+                            // app.
+                            if (MORE_DEBUG) {
+                                Slog.i(TAG, "Culling package " + entry.packageName
+                                        + " in full-backup queue but not eligible");
+                            }
+                            mFullBackupQueue.remove(0);
+                            headBusy = true; // force the while() condition
+                            continue;
+                        }
+
                         headBusy = mActivityManager.isAppForeground(appInfo.applicationInfo.uid);
 
                         if (headBusy) {
@@ -4762,7 +4867,6 @@
                             enqueueFullBackup(entry.packageName,
                                     nextEligible - MIN_FULL_BACKUP_INTERVAL);
                         }
-
                     } catch (NameNotFoundException nnf) {
                         // So, we think we want to back this up, but it turns out the package
                         // in question is no longer installed.  We want to drop it from the
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index c1a082b..499b706 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -114,13 +114,6 @@
     private static final int SERVICE_IBLUETOOTH = 1;
     private static final int SERVICE_IBLUETOOTHGATT = 2;
 
-    private static final String[] DEVICE_TYPE_NAMES = new String[] {
-            "???",
-            "BR/EDR",
-            "LE",
-            "DUAL"
-        };
-
     private final Context mContext;
     private static int mBleAppCount = 0;
 
@@ -131,6 +124,7 @@
     private final ContentResolver mContentResolver;
     private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
     private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
+    private IBinder mBluetoothBinder;
     private IBluetooth mBluetooth;
     private IBluetoothGatt mBluetoothGatt;
     private boolean mBinding;
@@ -242,6 +236,7 @@
 
         mContext = context;
         mBluetooth = null;
+        mBluetoothBinder = null;
         mBluetoothGatt = null;
         mBinding = false;
         mUnbinding = false;
@@ -678,6 +673,7 @@
                 }
 
                 if (DBG) Log.d(TAG, "Sending unbind request.");
+                mBluetoothBinder = null;
                 mBluetooth = null;
                 //Unbind
                 mContext.unbindService(mConnection);
@@ -1166,6 +1162,7 @@
                         mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
 
                         mBinding = false;
+                        mBluetoothBinder = service;
                         mBluetooth = IBluetooth.Stub.asInterface(service);
 
                         try {
@@ -1674,44 +1671,15 @@
     }
 
     @Override
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
-        writer.println("Bluetooth Status");
-        writer.println("  enabled: " + mEnable);
-        writer.println("  state: " + mState);
-        writer.println("  address: " + mAddress);
-        writer.println("  name: " + mName + "\n");
-        writer.flush();
-
-        if (mBluetooth == null) {
-            writer.println("Bluetooth Service not connected");
-        } else {
-            ParcelFileDescriptor pfd = null;
-            try {
-                writer.println("Bonded devices:");
-                for (BluetoothDevice device : mBluetooth.getBondedDevices()) {
-                    writer.println("  " + device.getAddress() +
-                            " [" + DEVICE_TYPE_NAMES[device.getType()] + "] " +
-                            device.getName());
-                }
-                writer.flush();
-
-                pfd = ParcelFileDescriptor.dup(fd);
-                mBluetooth.dump(pfd);
-            } catch (RemoteException re) {
-                writer.println("RemoteException while calling Bluetooth Service");
-            } catch (IOException ioe) {
-                writer.println("IOException attempting to dup() fd");
-            } finally {
-                if (pfd != null) {
-                    try {
-                        pfd.close();
-                    } catch (IOException ioe) {
-                        writer.println("IOException attempting to close() fd");
-                    }
-                }
-            }
+    public void dump(FileDescriptor fd, PrintWriter writer, String args[]) {
+      if (mBluetoothBinder == null) {
+        writer.println("Bluetooth Service not connected");
+      } else {
+        try {
+          mBluetoothBinder.dump(fd, args);
+        } catch (RemoteException re) {
+          writer.println("RemoteException while calling Bluetooth Service");
         }
+      }
     }
 }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 9927fd6..c3c3e3f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -87,6 +87,7 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -744,7 +745,7 @@
         mTestMode = SystemProperties.get("cm.test.mode").equals("true")
                 && SystemProperties.get("ro.build.type").equals("eng");
 
-        mTethering = new Tethering(mContext, mNetd, statsService, mHandler.getLooper());
+        mTethering = new Tethering(mContext, mNetd, statsService);
 
         mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
 
@@ -2686,6 +2687,21 @@
                 mTethering.getUpstreamIfaceTypes().length != 0);
     }
 
+    public void startTethering(int type, ResultReceiver receiver,
+            boolean showProvisioningUi) {
+        ConnectivityManager.enforceTetherChangePermission(mContext);
+        if (!isTetheringSupported()) {
+            receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);
+            return;
+        }
+        mTethering.startTethering(type, receiver, showProvisioningUi);
+    }
+
+    public void stopTethering(int type) {
+        ConnectivityManager.enforceTetherChangePermission(mContext);
+        mTethering.stopTethering(type);
+    }
+
     // Called when we lose the default network and have no replacement yet.
     // This will automatically be cleared after X seconds or a new default network
     // becomes CONNECTED, whichever happens first.  The timer is started by the
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 7bf1dea..c59ecec 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -108,6 +108,7 @@
 2826 backup_reset (Transport|3)
 2827 backup_initialize
 2828 backup_requested (Total|1|1),(Key-Value|1|1),(Full|1|1)
+2829 backup_quota_exceeded (Package|3)
 2830 restore_start (Transport|3),(Source|2|5)
 2831 restore_transport_failure
 2832 restore_agent_failure (Package|3),(Message|3)
@@ -119,6 +120,7 @@
 2842 full_backup_transport_failure
 2843 full_backup_success (Package|3)
 2844 full_restore_package (Package|3)
+2845 full_backup_quota_exceeded (Package|3)
 
 2850 backup_transport_lifecycle (Transport|3),(Bound|1|1)
 
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index 2aa0390..d6575e8 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -38,6 +38,7 @@
 import android.view.KeyEvent;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.server.statusbar.StatusBarManagerInternal;
 
 /**
@@ -270,7 +271,7 @@
             launched = handleCameraLaunchGesture(false /* useWakelock */,
                     StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
             if (launched) {
-                MetricsLogger.action(mContext, MetricsLogger.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
+                MetricsLogger.action(mContext, MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
                         (int) doubleTapInterval);
             }
         }
@@ -341,7 +342,7 @@
                 }
                 if (handleCameraLaunchGesture(true /* useWakelock */,
                         StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)) {
-                    MetricsLogger.action(mContext, MetricsLogger.ACTION_WIGGLE_CAMERA_GESTURE);
+                    MetricsLogger.action(mContext, MetricsEvent.ACTION_WIGGLE_CAMERA_GESTURE);
                     trackCameraLaunchEvent(event);
                 }
                 return;
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 377d52f..f6f05fe 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -78,7 +78,7 @@
     private final Context mContext;
 
     private final LockSettingsStorage mStorage;
-    private final LockSettingsStrongAuth mStrongAuth = new LockSettingsStrongAuth();
+    private final LockSettingsStrongAuth mStrongAuth;
 
     private LockPatternUtils mLockPatternUtils;
     private boolean mFirstCallToVold;
@@ -93,6 +93,7 @@
 
     public LockSettingsService(Context context) {
         mContext = context;
+        mStrongAuth = new LockSettingsStrongAuth(context);
         // Open the database
 
         mLockPatternUtils = new LockPatternUtils(context);
diff --git a/services/core/java/com/android/server/LockSettingsStrongAuth.java b/services/core/java/com/android/server/LockSettingsStrongAuth.java
index 0e4d5a7..551ceb8 100644
--- a/services/core/java/com/android/server/LockSettingsStrongAuth.java
+++ b/services/core/java/com/android/server/LockSettingsStrongAuth.java
@@ -20,6 +20,7 @@
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
 
 import android.app.trust.IStrongAuthTracker;
+import android.content.Context;
 import android.os.DeadObjectException;
 import android.os.Handler;
 import android.os.Message;
@@ -46,6 +47,11 @@
 
     private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
     private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
+    private final int mDefaultStrongAuthFlags;
+
+    public LockSettingsStrongAuth(Context context) {
+        mDefaultStrongAuthFlags = StrongAuthTracker.getDefaultFlags(context);
+    }
 
     private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
         for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
@@ -87,7 +93,7 @@
     }
 
     private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
-        int oldValue = mStrongAuthForUser.get(userId, LockPatternUtils.StrongAuthTracker.DEFAULT);
+        int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags);
         int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
                 ? STRONG_AUTH_NOT_REQUIRED
                 : (oldValue | strongAuthReason);
@@ -101,7 +107,7 @@
         int index = mStrongAuthForUser.indexOfKey(userId);
         if (index >= 0) {
             mStrongAuthForUser.removeAt(index);
-            notifyStrongAuthTrackers(StrongAuthTracker.DEFAULT, userId);
+            notifyStrongAuthTrackers(mDefaultStrongAuthFlags, userId);
         }
     }
 
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index dd19c6a..95f5734 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -186,7 +186,6 @@
 
     private final Handler mFgHandler;
     private final Handler mDaemonHandler;
-    private final PhoneStateListener mPhoneStateListener;
 
     private IBatteryStats mBatteryStats;
 
@@ -283,22 +282,6 @@
 
         mDaemonHandler = new Handler(FgThread.get().getLooper());
 
-        mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                mDaemonHandler.getLooper()) {
-            @Override
-            public void onDataConnectionRealTimeInfoChanged(
-                    DataConnectionRealTimeInfo dcRtInfo) {
-                if (DBG) Slog.d(TAG, "onDataConnectionRealTimeInfoChanged: " + dcRtInfo);
-                notifyInterfaceClassActivity(ConnectivityManager.TYPE_MOBILE,
-                        dcRtInfo.getDcPowerState(), dcRtInfo.getTime(), true);
-            }
-        };
-        TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
-        if (tm != null) {
-            tm.listen(mPhoneStateListener,
-                    PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO);
-        }
-
         // Add ourself to the Watchdog monitors.
         Watchdog.getInstance().addMonitor(this);
     }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 19a4851..820551d 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -34,7 +34,6 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.telephony.CellLocation;
-import android.telephony.DataConnectionRealTimeInfo;
 import android.telephony.Rlog;
 import android.telephony.TelephonyManager;
 import android.telephony.SubscriptionManager;
@@ -179,8 +178,6 @@
 
     private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
 
-    private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo();
-
     private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
 
     private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
@@ -262,7 +259,8 @@
                 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED, userHandle, 0));
             } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) {
                 Integer newDefaultSubIdObj = new Integer(intent.getIntExtra(
-                        PhoneConstants.SUBSCRIPTION_KEY, SubscriptionManager.getDefaultSubId()));
+                        PhoneConstants.SUBSCRIPTION_KEY,
+                        SubscriptionManager.getDefaultSubscriptionId()));
                 int newDefaultPhoneId = intent.getIntExtra(PhoneConstants.SLOT_KEY,
                     SubscriptionManager.getPhoneId(mDefaultSubId));
                 if (DBG) {
@@ -624,13 +622,6 @@
                             remove(r.binder);
                         }
                     }
-                    if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) {
-                        try {
-                            r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
-                    }
                     if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
                         try {
                             r.callback.onPreciseCallStateChanged(mPreciseCallState);
@@ -921,31 +912,6 @@
         }
     }
 
-    public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) {
-        if (!checkNotifyPermission("notifyDataConnectionRealTimeInfo()")) {
-            return;
-        }
-
-        synchronized (mRecords) {
-            mDcRtInfo = dcRtInfo;
-            for (Record r : mRecords) {
-                if (validateEventsAndUserLocked(r,
-                        PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO)) {
-                    try {
-                        if (DBG_LOC) {
-                            log("notifyDataConnectionRealTimeInfo: mDcRtInfo="
-                                    + mDcRtInfo + " r=" + r);
-                        }
-                        r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo);
-                    } catch (RemoteException ex) {
-                        mRemoveList.add(r.binder);
-                    }
-                }
-            }
-            handleRemoveListLocked();
-        }
-    }
-
     @Override
     public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) {
         if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
@@ -1370,7 +1336,6 @@
                 pw.println("  mCellLocation=" + mCellLocation[i]);
                 pw.println("  mCellInfo=" + mCellInfo.get(i));
             }
-            pw.println("  mDcRtInfo=" + mDcRtInfo);
             pw.println("registrations: count=" + recordCount);
             for (Record r : mRecords) {
                 pw.println("  " + r);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index b86b3fd..d0006aa 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2486,16 +2486,20 @@
     }
 
     @Override
-    public void finishSession(IAccountManagerResponse response,
+    public void finishSessionAsUser(IAccountManagerResponse response,
             @NonNull Bundle sessionBundle,
             boolean expectActivityLaunch,
-            Bundle appInfo) {
+            Bundle appInfo,
+            int userId) {
+        int callingUid = Binder.getCallingUid();
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG,
-                    "finishSession: response " + response
+                    "finishSession: response "+ response
                             + ", expectActivityLaunch " + expectActivityLaunch
-                            + ", caller's uid " + Binder.getCallingUid()
-                            + ", pid " + Binder.getCallingPid());
+                            + ", caller's uid " + callingUid
+                            + ", caller's user id " + UserHandle.getCallingUserId()
+                            + ", pid " + Binder.getCallingPid()
+                            + ", for user id " + userId);
         }
         if (response == null) {
             throw new IllegalArgumentException("response is null");
@@ -2507,17 +2511,24 @@
             throw new IllegalArgumentException("sessionBundle is empty");
         }
 
-        final int uid = Binder.getCallingUid();
+        // Only allow the system process to finish session for other users
+        if (isCrossUser(callingUid, userId)) {
+            throw new SecurityException(
+                    String.format(
+                            "User %s trying to finish session for %s without cross user permission",
+                            UserHandle.getCallingUserId(),
+                            userId));
+        }
+
         // Only allow system to finish session
-        if (!isSystemUid(uid)) {
+        if (!isSystemUid(callingUid)) {
             String msg = String.format(
-                    "uid %s cannot finish session.",
-                    uid);
+                    "uid %s cannot finish session because it's not system uid.",
+                    callingUid);
             throw new SecurityException(msg);
         }
 
-        final int userId = UserHandle.getUserId(uid);
-        if (!canUserModifyAccounts(userId, uid)) {
+        if (!canUserModifyAccounts(userId, callingUid)) {
             sendErrorResponse(response,
                     AccountManager.ERROR_CODE_USER_RESTRICTED,
                     "User is not allowed to add an account!");
@@ -2559,7 +2570,7 @@
             }
 
             // Add info that may be used by add account or update credentials flow.
-            decryptedBundle.putInt(AccountManager.KEY_CALLER_UID, uid);
+            decryptedBundle.putInt(AccountManager.KEY_CALLER_UID, callingUid);
             decryptedBundle.putInt(AccountManager.KEY_CALLER_PID, pid);
         } catch (GeneralSecurityException e) {
             if (Log.isLoggable(TAG, Log.DEBUG)) {
@@ -2572,7 +2583,7 @@
             return;
         }
 
-        if (!canUserModifyAccountsForType(userId, accountType, uid)) {
+        if (!canUserModifyAccountsForType(userId, accountType, callingUid)) {
             sendErrorResponse(
                     response,
                     AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE,
@@ -2589,7 +2600,7 @@
                     accounts,
                     DebugDbHelper.ACTION_CALLED_ACCOUNT_SESSION_FINISH,
                     TABLE_ACCOUNTS,
-                    uid);
+                    callingUid);
             new Session(
                     accounts,
                     response,
@@ -4255,21 +4266,6 @@
         }
     }
 
-    private boolean isPermitted(String opPackageName, int callingUid, String... permissions) {
-        for (String perm : permissions) {
-            if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "  caller uid " + callingUid + " has " + perm);
-                }
-                final int opCode = AppOpsManager.permissionToOpCode(perm);
-                if (opCode == AppOpsManager.OP_NONE || mAppOpsManager.noteOp(
-                        opCode, callingUid, opPackageName) == AppOpsManager.MODE_ALLOWED) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
 
     private int handleIncomingUser(int userId) {
         try {
@@ -4344,12 +4340,50 @@
 
     private List<String> getTypesVisibleToCaller(int callingUid, int userId,
             String opPackageName) {
-        boolean isPermitted =
-                isPermitted(opPackageName, callingUid, Manifest.permission.GET_ACCOUNTS,
-                        Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
+        List<String> permissionsToCheck = new ArrayList<String>(2);
+        permissionsToCheck.add(Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
+        try {
+            ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
+                    opPackageName, 0 /* flags */);
+            /*
+             * At or before SDK 23, clients discover all the accounts in their
+             * user profile (via AccountManager.getAccounts(...)) by declaring
+             * the GET_ACCOUNTS permission.
+             *
+             * After SDK 23 the GET_ACCOUNTS permission is deprecated.  Instead
+             * apps will be able to retrieve those accounts managed by
+             * authenticators sharing a package signature without any special
+             * permissions. The only clients able to discover all the accounts
+             * on the device will be those with the GET_ACCOUNTS_PRVILEGED
+             * system permission.
+             */
+            if (23 >= appInfo.targetSdkVersion) {
+                permissionsToCheck.add(Manifest.permission.GET_ACCOUNTS);
+            }
+        } catch (NameNotFoundException e) {
+            // No application associated with the specified package.
+            Log.w(TAG, "No application associated with package: " + opPackageName);
+        }
+        boolean isPermitted = isPermitted(opPackageName, callingUid, permissionsToCheck);
         return getTypesForCaller(callingUid, userId, isPermitted);
     }
 
+    private boolean isPermitted(String opPackageName, int callingUid, List<String> permissions) {
+        for (String perm : permissions) {
+            if (mContext.checkCallingOrSelfPermission(perm) == PackageManager.PERMISSION_GRANTED) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "  caller uid " + callingUid + " has " + perm);
+                }
+                final int opCode = AppOpsManager.permissionToOpCode(perm);
+                if (opCode == AppOpsManager.OP_NONE || mAppOpsManager.noteOp(
+                        opCode, callingUid, opPackageName) == AppOpsManager.MODE_ALLOWED) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private List<String> getTypesManagedByCaller(int callingUid, int userId) {
         return getTypesForCaller(callingUid, userId, false);
     }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 7ba6338..8c0ec78 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2775,7 +2775,7 @@
         }
 
         if (anrMessage != null) {
-            mAm.appNotResponding(proc, null, null, false, anrMessage);
+            mAm.mAppErrors.appNotResponding(proc, null, null, false, anrMessage);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8c2090e..2c55ee2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -141,6 +141,7 @@
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -187,6 +188,7 @@
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.service.voice.IVoiceInteractionSession;
+import android.service.voice.VoiceInteractionManagerInternal;
 import android.service.voice.VoiceInteractionSession;
 import android.text.format.DateUtils;
 import android.text.format.Time;
@@ -201,7 +203,6 @@
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.SparseBooleanArray;
 import android.util.TimeUtils;
 import android.util.Xml;
 import android.view.Display;
@@ -269,13 +270,13 @@
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
+import static android.provider.Settings.System.FONT_SCALE;
 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
 import static com.android.internal.util.XmlUtils.readIntAttribute;
 import static com.android.internal.util.XmlUtils.readLongAttribute;
 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
 import static com.android.internal.util.XmlUtils.writeIntAttribute;
 import static com.android.internal.util.XmlUtils.writeLongAttribute;
-import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
@@ -390,7 +391,7 @@
     // The flags that are set for all calls we make to the package manager.
     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
 
-    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
+    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
 
@@ -533,6 +534,7 @@
     // default actuion automatically.  Important for devices without direct input
     // devices.
     private boolean mShowDialogs = true;
+    private boolean mInVrMode = false;
 
     BroadcastQueue mFgBroadcastQueue;
     BroadcastQueue mBgBroadcastQueue;
@@ -595,6 +597,12 @@
 
     final UserController mUserController;
 
+    final AppErrors mAppErrors;
+
+    public boolean canShowErrorDialogs() {
+        return mShowDialogs && !mSleeping && !mShuttingDown;
+    }
+
     public class PendingAssistExtras extends Binder implements Runnable {
         public final ActivityRecord activity;
         public final Bundle extras;
@@ -665,38 +673,6 @@
     ProcessRecord mHeavyWeightProcess = null;
 
     /**
-     * The last time that various processes have crashed.
-     */
-    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
-
-    /**
-     * Information about a process that is currently marked as bad.
-     */
-    static final class BadProcessInfo {
-        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
-            this.time = time;
-            this.shortMsg = shortMsg;
-            this.longMsg = longMsg;
-            this.stack = stack;
-        }
-
-        final long time;
-        final String shortMsg;
-        final String longMsg;
-        final String stack;
-    }
-
-    /**
-     * Set of applications that we consider to be bad, and will reject
-     * incoming broadcasts from (which the user has no control over).
-     * Processes are added to this set when they have crashed twice within
-     * a minimum amount of time; they are removed from it when they are
-     * later restarted (hopefully due to some user action).  The value is the
-     * time it was added to the list.
-     */
-    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
-
-    /**
      * All of the processes we currently have running organized by pid.
      * The keys are the pid running the application.
      *
@@ -1014,6 +990,25 @@
 
     CoreSettingsObserver mCoreSettingsObserver;
 
+    FontScaleSettingObserver mFontScaleSettingObserver;
+
+    private final class FontScaleSettingObserver extends ContentObserver {
+        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
+
+        public FontScaleSettingObserver() {
+            super(mHandler);
+            ContentResolver resolver = mContext.getContentResolver();
+            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (mFontScaleUri.equals(uri)) {
+                updateFontScaleIfNeeded();
+            }
+        }
+    }
+
     /**
      * Thread-local storage used to carry caller permissions over through
      * indirect content-provider access.
@@ -1329,8 +1324,6 @@
     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
 
-    ArraySet<String> mAppsNotReportingCrashes;
-
     /**
      * Runtime CPU use collection thread.  This object's lock is used to
      * perform synchronization with the thread (notifying it to run).
@@ -1450,6 +1443,7 @@
     static final int LOG_STACK_STATE = 62;
     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 FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1488,80 +1482,11 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
             case SHOW_ERROR_UI_MSG: {
-                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
-                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
-                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
-                synchronized (ActivityManagerService.this) {
-                    ProcessRecord proc = (ProcessRecord)data.get("app");
-                    AppErrorResult res = (AppErrorResult) data.get("result");
-                    if (proc != null && proc.crashDialog != null) {
-                        Slog.e(TAG, "App already has crash dialog: " + proc);
-                        if (res != null) {
-                            res.set(0);
-                        }
-                        return;
-                    }
-                    boolean isBackground = (UserHandle.getAppId(proc.uid)
-                            >= Process.FIRST_APPLICATION_UID
-                            && proc.pid != MY_PID);
-                    for (int userId : mUserController.getCurrentProfileIdsLocked()) {
-                        isBackground &= (proc.userId != userId);
-                    }
-                    if (isBackground && !showBackground) {
-                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
-                        if (res != null) {
-                            res.set(0);
-                        }
-                        return;
-                    }
-                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
-                            mAppsNotReportingCrashes.contains(proc.info.packageName);
-                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
-                        Dialog d = new AppErrorDialog(mContext,
-                                ActivityManagerService.this, res, proc);
-                        d.show();
-                        proc.crashDialog = d;
-                    } else {
-                        // The device is asleep, so just pretend that the user
-                        // saw a crash dialog and hit "force quit".
-                        if (res != null) {
-                            res.set(0);
-                        }
-                    }
-                }
-
+                mAppErrors.handleShowAppErrorUi(msg);
                 ensureBootCompleted();
             } break;
             case SHOW_NOT_RESPONDING_UI_MSG: {
-                synchronized (ActivityManagerService.this) {
-                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
-                    ProcessRecord proc = (ProcessRecord)data.get("app");
-                    if (proc != null && proc.anrDialog != null) {
-                        Slog.e(TAG, "App already has anr dialog: " + proc);
-                        return;
-                    }
-
-                    Intent intent = new Intent("android.intent.action.ANR");
-                    if (!mProcessesReady) {
-                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
-                                | Intent.FLAG_RECEIVER_FOREGROUND);
-                    }
-                    broadcastIntentLocked(null, null, intent,
-                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
-                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
-
-                    if (mShowDialogs) {
-                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
-                                mContext, proc, (ActivityRecord)data.get("activity"),
-                                msg.arg1 != 0);
-                        d.show();
-                        proc.anrDialog = d;
-                    } else {
-                        // Just kill the app if there is no dialog to be shown.
-                        killAppAtUsersRequest(proc, null);
-                    }
-                }
-
+                mAppErrors.handleShowAnrUi(msg);
                 ensureBootCompleted();
             } break;
             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
@@ -2033,6 +1958,20 @@
                 }
                 break;
             }
+            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_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).onPinnedActivityRestartAttempt();
+                        } 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;
@@ -2182,7 +2121,15 @@
             } break;
             case VR_MODE_CHANGE_MSG: {
                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
-                vrService.setVrMode(msg.arg1 != 0);
+                final boolean vrMode = msg.arg1 != 0;
+                vrService.setVrMode(vrMode);
+
+                if (mInVrMode != vrMode) {
+                    synchronized (ActivityManagerService.this) {
+                        mInVrMode = vrMode;
+                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
+                    }
+                }
             } break;
             }
         }
@@ -2464,6 +2411,7 @@
 
         mServices = new ActiveServices(this);
         mProviderMap = new ProviderMap(this);
+        mAppErrors = new AppErrors(mContext, this);
 
         // TODO: Move creation of battery stats service outside of activity manager service.
         File dataDir = Environment.getDataDirectory();
@@ -2803,16 +2751,21 @@
         } else {
             r.appTimeTracker = null;
         }
+        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
+        // TODO: Probably not, because we don't want to resume voice on switching
+        // back to this activity
         if (r.task.voiceInteractor != null) {
             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
         } else {
             finishRunningVoiceLocked();
-            if (last != null && last.task.voiceSession != null) {
+            IVoiceInteractionSession session;
+            if (last != null && ((session = last.task.voiceSession) != null
+                    || (session = last.voiceSession) != null)) {
                 // We had been in a voice interaction session, but now focused has
                 // move to something different.  Just finish the session, we can't
                 // return to it and retain the proper state and synchronization with
                 // the voice interaction service.
-                finishVoiceTask(last.task.voiceSession);
+                finishVoiceTask(session);
             }
         }
         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
@@ -2977,7 +2930,7 @@
         return index;
     }
 
-    private static void killProcessGroup(int uid, int pid) {
+    static void killProcessGroup(int uid, int pid) {
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
         Process.killProcessGroup(uid, pid);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -3299,7 +3252,7 @@
             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
                 // If we are in the background, then check to see if this process
                 // is bad.  If so, we will just silently fail.
-                if (mBadProcesses.get(info.processName, info.uid) != null) {
+                if (mAppErrors.isBadProcessLocked(info)) {
                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
                             + "/" + info.processName);
                     return null;
@@ -3311,12 +3264,12 @@
                 // if it had been bad.
                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
                         + "/" + info.processName);
-                mProcessCrashTimes.remove(info.processName, info.uid);
-                if (mBadProcesses.get(info.processName, info.uid) != null) {
+                mAppErrors.resetProcessCrashTimeLocked(info);
+                if (mAppErrors.isBadProcessLocked(info)) {
                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
                             UserHandle.getUserId(info.uid), info.uid,
                             info.processName);
-                    mBadProcesses.remove(info.processName, info.uid);
+                    mAppErrors.clearBadProcessLocked(info);
                     if (app != null) {
                         app.bad = false;
                     }
@@ -4256,6 +4209,66 @@
     }
 
     @Override
+    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
+            throws RemoteException {
+        Slog.i(TAG, "Activity tried to startVoiceInteraction");
+        synchronized (this) {
+            ActivityRecord activity = getFocusedStack().topActivity();
+            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
+                throw new SecurityException("Only focused activity can call startVoiceInteraction");
+            }
+            if (mRunningVoice != null || activity.task.voiceSession != null
+                    || activity.voiceSession != null) {
+                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
+                return;
+            }
+            if (activity.pendingVoiceInteractionStart) {
+                Slog.w(TAG, "Pending start of voice interaction already.");
+                return;
+            }
+            activity.pendingVoiceInteractionStart = true;
+        }
+        LocalServices.getService(VoiceInteractionManagerInternal.class)
+                .startLocalVoiceInteraction(callingActivity, options);
+    }
+
+    @Override
+    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
+        LocalServices.getService(VoiceInteractionManagerInternal.class)
+                .stopLocalVoiceInteraction(callingActivity);
+    }
+
+    @Override
+    public boolean supportsLocalVoiceInteraction() throws RemoteException {
+        return LocalServices.getService(VoiceInteractionManagerInternal.class)
+                .supportsLocalVoiceInteraction();
+    }
+
+    void onLocalVoiceInteractionStartedLocked(IBinder activity,
+            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
+        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
+        if (activityToCallback == null) return;
+        activityToCallback.setVoiceSessionLocked(voiceSession);
+
+        // Inform the activity
+        try {
+            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
+                    voiceInteractor);
+            long token = Binder.clearCallingIdentity();
+            try {
+                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+            // TODO: VI Should we cache the activity so that it's easier to find later
+            // rather than scan through all the stacks and activities?
+        } catch (RemoteException re) {
+            activityToCallback.clearVoiceSessionLocked();
+            // TODO: VI Should this terminate the voice session?
+        }
+    }
+
+    @Override
     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
         synchronized (this) {
             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
@@ -4664,46 +4677,7 @@
         }
 
         synchronized(this) {
-            ProcessRecord proc = null;
-
-            // Figure out which process to kill.  We don't trust that initialPid
-            // still has any relation to current pids, so must scan through the
-            // list.
-            synchronized (mPidsSelfLocked) {
-                for (int i=0; i<mPidsSelfLocked.size(); i++) {
-                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
-                    if (p.uid != uid) {
-                        continue;
-                    }
-                    if (p.pid == initialPid) {
-                        proc = p;
-                        break;
-                    }
-                    if (p.pkgList.containsKey(packageName)) {
-                        proc = p;
-                    }
-                }
-            }
-
-            if (proc == null) {
-                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
-                        + " initialPid=" + initialPid
-                        + " packageName=" + packageName);
-                return;
-            }
-
-            if (proc.thread != null) {
-                if (proc.pid == Process.myPid()) {
-                    Log.w(TAG, "crashApplication: trying to crash self!");
-                    return;
-                }
-                long ident = Binder.clearCallingIdentity();
-                try {
-                    proc.thread.scheduleCrash(message);
-                } catch (RemoteException e) {
-                }
-                Binder.restoreCallingIdentity(ident);
-            }
+            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
         }
     }
 
@@ -4747,9 +4721,11 @@
 
     @Override
     public void finishVoiceTask(IVoiceInteractionSession session) {
-        synchronized(this) {
+        synchronized (this) {
             final long origId = Binder.clearCallingIdentity();
             try {
+                // TODO: VI Consider treating local voice interactions and voice tasks
+                // differently here
                 mStackSupervisor.finishVoiceTask(session);
             } finally {
                 Binder.restoreCallingIdentity(origId);
@@ -5182,169 +5158,6 @@
         }
     }
 
-    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
-            ActivityRecord parent, boolean aboveSystem, final String annotation) {
-        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
-        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
-
-        if (mController != null) {
-            try {
-                // 0 == continue, -1 = kill process immediately
-                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
-                if (res < 0 && app.pid != MY_PID) {
-                    app.kill("anr", true);
-                }
-            } catch (RemoteException e) {
-                mController = null;
-                Watchdog.getInstance().setActivityController(null);
-            }
-        }
-
-        long anrTime = SystemClock.uptimeMillis();
-        if (MONITOR_CPU_USAGE) {
-            updateCpuStatsNow();
-        }
-
-        synchronized (this) {
-            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
-            if (mShuttingDown) {
-                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
-                return;
-            } else if (app.notResponding) {
-                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
-                return;
-            } else if (app.crashing) {
-                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
-                return;
-            }
-
-            // In case we come through here for the same app before completing
-            // this one, mark as anring now so we will bail out.
-            app.notResponding = true;
-
-            // Log the ANR to the event log.
-            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
-                    app.processName, app.info.flags, annotation);
-
-            // Dump thread traces as quickly as we can, starting with "interesting" processes.
-            firstPids.add(app.pid);
-
-            int parentPid = app.pid;
-            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
-            if (parentPid != app.pid) firstPids.add(parentPid);
-
-            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
-
-            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
-                ProcessRecord r = mLruProcesses.get(i);
-                if (r != null && r.thread != null) {
-                    int pid = r.pid;
-                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
-                        if (r.persistent) {
-                            firstPids.add(pid);
-                        } else {
-                            lastPids.put(pid, Boolean.TRUE);
-                        }
-                    }
-                }
-            }
-        }
-
-        // Log the ANR to the main log.
-        StringBuilder info = new StringBuilder();
-        info.setLength(0);
-        info.append("ANR in ").append(app.processName);
-        if (activity != null && activity.shortComponentName != null) {
-            info.append(" (").append(activity.shortComponentName).append(")");
-        }
-        info.append("\n");
-        info.append("PID: ").append(app.pid).append("\n");
-        if (annotation != null) {
-            info.append("Reason: ").append(annotation).append("\n");
-        }
-        if (parent != null && parent != activity) {
-            info.append("Parent: ").append(parent.shortComponentName).append("\n");
-        }
-
-        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
-
-        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
-                NATIVE_STACKS_OF_INTEREST);
-
-        String cpuInfo = null;
-        if (MONITOR_CPU_USAGE) {
-            updateCpuStatsNow();
-            synchronized (mProcessCpuTracker) {
-                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
-            }
-            info.append(processCpuTracker.printCurrentLoad());
-            info.append(cpuInfo);
-        }
-
-        info.append(processCpuTracker.printCurrentState(anrTime));
-
-        Slog.e(TAG, info.toString());
-        if (tracesFile == null) {
-            // There is no trace file, so dump (only) the alleged culprit's threads to the log
-            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
-        }
-
-        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
-                cpuInfo, tracesFile, null);
-
-        if (mController != null) {
-            try {
-                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
-                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
-                if (res != 0) {
-                    if (res < 0 && app.pid != MY_PID) {
-                        app.kill("anr", true);
-                    } else {
-                        synchronized (this) {
-                            mServices.scheduleServiceTimeoutLocked(app);
-                        }
-                    }
-                    return;
-                }
-            } catch (RemoteException e) {
-                mController = null;
-                Watchdog.getInstance().setActivityController(null);
-            }
-        }
-
-        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
-        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
-
-        synchronized (this) {
-            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
-
-            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
-                app.kill("bg anr", true);
-                return;
-            }
-
-            // Set the app's notResponding state, and look up the errorReportReceiver
-            makeAppNotRespondingLocked(app,
-                    activity != null ? activity.shortComponentName : null,
-                    annotation != null ? "ANR " + annotation : "ANR",
-                    info.toString());
-
-            // Bring up the infamous App Not Responding dialog
-            Message msg = Message.obtain();
-            HashMap<String, Object> map = new HashMap<String, Object>();
-            msg.what = SHOW_NOT_RESPONDING_UI_MSG;
-            msg.obj = map;
-            msg.arg1 = aboveSystem ? 1 : 0;
-            map.put("app", app);
-            if (activity != null) {
-                map.put("activity", activity);
-            }
-
-            mUiHandler.sendMessage(msg);
-        }
-    }
-
     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
         if (!mLaunchWarningShown) {
             mLaunchWarningShown = true;
@@ -5967,33 +5780,7 @@
                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
             }
 
-            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
-            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
-                SparseArray<Long> ba = pmap.valueAt(ip);
-                for (i = ba.size() - 1; i >= 0; i--) {
-                    boolean remove = false;
-                    final int entUid = ba.keyAt(i);
-                    if (packageName != null) {
-                        if (userId == UserHandle.USER_ALL) {
-                            if (UserHandle.getAppId(entUid) == appId) {
-                                remove = true;
-                            }
-                        } else {
-                            if (entUid == UserHandle.getUid(userId, appId)) {
-                                remove = true;
-                            }
-                        }
-                    } else if (UserHandle.getUserId(entUid) == userId) {
-                        remove = true;
-                    }
-                    if (remove) {
-                        ba.removeAt(i);
-                    }
-                }
-                if (ba.size() == 0) {
-                    pmap.removeAt(ip);
-                }
-            }
+            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
         }
 
         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
@@ -6158,7 +5945,7 @@
         }
     }
 
-    private final boolean removeProcessLocked(ProcessRecord app,
+    boolean removeProcessLocked(ProcessRecord app,
             boolean callerWillRestart, boolean allowRestart, String reason) {
         final String name = app.processName;
         final int uid = app.uid;
@@ -8891,6 +8678,11 @@
                     continue;
                 }
 
+                if (tr.realActivitySuspended) {
+                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
+                    continue;
+                }
+
                 // Return the entry if desired by the caller.  We always return
                 // the first entry, because callers always expect this to be the
                 // foreground app.  We may filter others if the caller has
@@ -10821,7 +10613,7 @@
 
         final long token = Binder.clearCallingIdentity();
         try {
-            appNotResponding(host, null, null, false, "ContentProvider not responding");
+            mAppErrors.appNotResponding(host, null, null, false, "ContentProvider not responding");
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -10848,6 +10640,7 @@
         }
 
         mCoreSettingsObserver = new CoreSettingsObserver(this);
+        mFontScaleSettingObserver = new FontScaleSettingObserver();
 
         //mUsageStatsService.monitorPackages();
     }
@@ -11107,6 +10900,7 @@
     }
 
     void finishRunningVoiceLocked() {
+        Slog.d(TAG, "finishRunningVoiceLocked()  >>>>");
         if (mRunningVoice != null) {
             mRunningVoice = null;
             mVoiceWakeLock.release();
@@ -11184,6 +10978,16 @@
         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
     }
 
+    /**
+     * Notifies all listeners when an attempt was made to start an an activity that is already
+     * running in the pinned stack and the activity was not actually started, but the task is
+     * either brought to the front or a new Intent is delivered to it.
+     */
+    void notifyPinnedActivityRestartAttemptLocked() {
+        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
+        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
+    }
+
     @Override
     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
@@ -11250,6 +11054,7 @@
     }
 
     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
+        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
             boolean wasRunningVoice = mRunningVoice != null;
@@ -11572,7 +11377,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
+                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
                 }
             });
         }
@@ -12366,17 +12171,8 @@
                     com.android.internal.R.dimen.thumbnail_height);
             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
-            final String appsNotReportingCrashes = res.getString(
-                    com.android.internal.R.string.config_appsNotReportingCrashes);
-            if (appsNotReportingCrashes != null) {
-                final String[] split = appsNotReportingCrashes.split(",");
-                if (split.length > 0) {
-                    mAppsNotReportingCrashes = new ArraySet<>();
-                    for (int i = 0; i < split.length; i++) {
-                        mAppsNotReportingCrashes.add(split[i]);
-                    }
-                }
-            }
+            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
+                    com.android.internal.R.string.config_appsNotReportingCrashes));
         }
     }
 
@@ -12781,174 +12577,12 @@
         }
     }
 
-    private boolean makeAppCrashingLocked(ProcessRecord app,
-            String shortMsg, String longMsg, String stackTrace) {
-        app.crashing = true;
-        app.crashingReport = generateProcessError(app,
-                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
-        startAppProblemLocked(app);
-        app.stopFreezingAllLocked();
-        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
-    }
-
-    private void makeAppNotRespondingLocked(ProcessRecord app,
-            String activity, String shortMsg, String longMsg) {
-        app.notResponding = true;
-        app.notRespondingReport = generateProcessError(app,
-                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
-                activity, shortMsg, longMsg, null);
-        startAppProblemLocked(app);
-        app.stopFreezingAllLocked();
-    }
-
-    /**
-     * Generate a process error record, suitable for attachment to a ProcessRecord.
-     *
-     * @param app The ProcessRecord in which the error occurred.
-     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
-     *                      ActivityManager.AppErrorStateInfo
-     * @param activity The activity associated with the crash, if known.
-     * @param shortMsg Short message describing the crash.
-     * @param longMsg Long message describing the crash.
-     * @param stackTrace Full crash stack trace, may be null.
-     *
-     * @return Returns a fully-formed AppErrorStateInfo record.
-     */
-    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
-            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
-        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
-
-        report.condition = condition;
-        report.processName = app.processName;
-        report.pid = app.pid;
-        report.uid = app.info.uid;
-        report.tag = activity;
-        report.shortMsg = shortMsg;
-        report.longMsg = longMsg;
-        report.stackTrace = stackTrace;
-
-        return report;
-    }
-
     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
         synchronized (this) {
-            app.crashing = false;
-            app.crashingReport = null;
-            app.notResponding = false;
-            app.notRespondingReport = null;
-            if (app.anrDialog == fromDialog) {
-                app.anrDialog = null;
-            }
-            if (app.waitDialog == fromDialog) {
-                app.waitDialog = null;
-            }
-            if (app.pid > 0 && app.pid != MY_PID) {
-                handleAppCrashLocked(app, "user-terminated" /*reason*/,
-                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
-                app.kill("user request after error", true);
-            }
+            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
         }
     }
 
-    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
-            String shortMsg, String longMsg, String stackTrace) {
-        long now = SystemClock.uptimeMillis();
-
-        Long crashTime;
-        if (!app.isolated) {
-            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
-        } else {
-            crashTime = null;
-        }
-        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
-            // This process loses!
-            Slog.w(TAG, "Process " + app.info.processName
-                    + " has crashed too many times: killing!");
-            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
-                    app.userId, app.info.processName, app.uid);
-            mStackSupervisor.handleAppCrashLocked(app);
-            if (!app.persistent) {
-                // We don't want to start this process again until the user
-                // explicitly does so...  but for persistent process, we really
-                // need to keep it running.  If a persistent process is actually
-                // repeatedly crashing, then badness for everyone.
-                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
-                        app.info.processName);
-                if (!app.isolated) {
-                    // XXX We don't have a way to mark isolated processes
-                    // as bad, since they don't have a peristent identity.
-                    mBadProcesses.put(app.info.processName, app.uid,
-                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
-                    mProcessCrashTimes.remove(app.info.processName, app.uid);
-                }
-                app.bad = true;
-                app.removed = true;
-                // Don't let services in this process be restarted and potentially
-                // annoy the user repeatedly.  Unless it is persistent, since those
-                // processes run critical code.
-                removeProcessLocked(app, false, false, "crash");
-                mStackSupervisor.resumeFocusedStackTopActivityLocked();
-                return false;
-            }
-            mStackSupervisor.resumeFocusedStackTopActivityLocked();
-        } else {
-            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
-        }
-
-        // Bump up the crash count of any services currently running in the proc.
-        for (int i=app.services.size()-1; i>=0; i--) {
-            // Any services running in the application need to be placed
-            // back in the pending list.
-            ServiceRecord sr = app.services.valueAt(i);
-            sr.crashCount++;
-        }
-
-        // If the crashing process is what we consider to be the "home process" and it has been
-        // replaced by a third-party app, clear the package preferred activities from packages
-        // with a home activity running in the process to prevent a repeatedly crashing app
-        // from blocking the user to manually clear the list.
-        final ArrayList<ActivityRecord> activities = app.activities;
-        if (app == mHomeProcess && activities.size() > 0
-                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                final ActivityRecord r = activities.get(activityNdx);
-                if (r.isHomeActivity()) {
-                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
-                    try {
-                        ActivityThread.getPackageManager()
-                                .clearPackagePreferredActivities(r.packageName);
-                    } catch (RemoteException c) {
-                        // pm is in same process, this will never happen.
-                    }
-                }
-            }
-        }
-
-        if (!app.isolated) {
-            // XXX Can't keep track of crash times for isolated processes,
-            // because they don't have a perisistent identity.
-            mProcessCrashTimes.put(app.info.processName, app.uid, now);
-        }
-
-        if (app.crashHandler != null) mHandler.post(app.crashHandler);
-        return true;
-    }
-
-    void startAppProblemLocked(ProcessRecord app) {
-        // If this app is not running under the current user, then we
-        // can't give it a report button because that would require
-        // launching the report UI under a different user.
-        app.errorReportReceiver = null;
-
-        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
-            if (app.userId == userId) {
-                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
-                        mContext, app.info.packageName, app.info.flags);
-            }
-        }
-        skipCurrentReceiverLocked(app);
-    }
-
     void skipCurrentReceiverLocked(ProcessRecord app) {
         for (BroadcastQueue queue : mBroadcastQueues) {
             queue.skipCurrentReceiverLocked(app);
@@ -12984,7 +12618,7 @@
 
         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
 
-        crashApplication(r, crashInfo);
+        mAppErrors.crashApplication(r, crashInfo);
     }
 
     public void handleApplicationStrictModeViolation(
@@ -13195,7 +12829,7 @@
         if (r != null && r.pid != Process.myPid() &&
                 Settings.Global.getInt(mContext.getContentResolver(),
                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
-            crashApplication(r, crashInfo);
+            mAppErrors.crashApplication(r, crashInfo);
             return true;
         } else {
             return false;
@@ -13404,164 +13038,6 @@
         }
     }
 
-    /**
-     * Bring up the "unexpected error" dialog box for a crashing app.
-     * Deal with edge cases (intercepts from instrumented applications,
-     * ActivityController, error intent receivers, that sort of thing).
-     * @param r the application crashing
-     * @param crashInfo describing the failure
-     */
-    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
-        long timeMillis = System.currentTimeMillis();
-        String shortMsg = crashInfo.exceptionClassName;
-        String longMsg = crashInfo.exceptionMessage;
-        String stackTrace = crashInfo.stackTrace;
-        if (shortMsg != null && longMsg != null) {
-            longMsg = shortMsg + ": " + longMsg;
-        } else if (shortMsg != null) {
-            longMsg = shortMsg;
-        }
-
-        AppErrorResult result = new AppErrorResult();
-        synchronized (this) {
-            if (mController != null) {
-                try {
-                    String name = r != null ? r.processName : null;
-                    int pid = r != null ? r.pid : Binder.getCallingPid();
-                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
-                    if (!mController.appCrashed(name, pid,
-                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
-                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
-                                && "Native crash".equals(crashInfo.exceptionClassName)) {
-                            Slog.w(TAG, "Skip killing native crashed app " + name
-                                    + "(" + pid + ") during testing");
-                        } else {
-                            Slog.w(TAG, "Force-killing crashed app " + name
-                                    + " at watcher's request");
-                            if (r != null) {
-                                r.kill("crash", true);
-                            } else {
-                                // Huh.
-                                Process.killProcess(pid);
-                                killProcessGroup(uid, pid);
-                            }
-                        }
-                        return;
-                    }
-                } catch (RemoteException e) {
-                    mController = null;
-                    Watchdog.getInstance().setActivityController(null);
-                }
-            }
-
-            final long origId = Binder.clearCallingIdentity();
-
-            // If this process is running instrumentation, finish it.
-            if (r != null && r.instrumentationClass != null) {
-                Slog.w(TAG, "Error in app " + r.processName
-                      + " running instrumentation " + r.instrumentationClass + ":");
-                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
-                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
-                Bundle info = new Bundle();
-                info.putString("shortMsg", shortMsg);
-                info.putString("longMsg", longMsg);
-                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
-                Binder.restoreCallingIdentity(origId);
-                return;
-            }
-
-            // Log crash in battery stats.
-            if (r != null) {
-                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
-            }
-
-            // If we can't identify the process or it's already exceeded its crash quota,
-            // quit right away without showing a crash dialog.
-            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
-                Binder.restoreCallingIdentity(origId);
-                return;
-            }
-
-            Message msg = Message.obtain();
-            msg.what = SHOW_ERROR_UI_MSG;
-            HashMap data = new HashMap();
-            data.put("result", result);
-            data.put("app", r);
-            msg.obj = data;
-            mUiHandler.sendMessage(msg);
-
-            Binder.restoreCallingIdentity(origId);
-        }
-
-        int res = result.get();
-
-        Intent appErrorIntent = null;
-        synchronized (this) {
-            if (r != null && !r.isolated) {
-                // XXX Can't keep track of crash time for isolated processes,
-                // since they don't have a persistent identity.
-                mProcessCrashTimes.put(r.info.processName, r.uid,
-                        SystemClock.uptimeMillis());
-            }
-            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
-                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
-            }
-        }
-
-        if (appErrorIntent != null) {
-            try {
-                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
-            } catch (ActivityNotFoundException e) {
-                Slog.w(TAG, "bug report receiver dissappeared", e);
-            }
-        }
-    }
-
-    Intent createAppErrorIntentLocked(ProcessRecord r,
-            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
-        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
-        if (report == null) {
-            return null;
-        }
-        Intent result = new Intent(Intent.ACTION_APP_ERROR);
-        result.setComponent(r.errorReportReceiver);
-        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
-        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return result;
-    }
-
-    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
-            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
-        if (r.errorReportReceiver == null) {
-            return null;
-        }
-
-        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
-            return null;
-        }
-
-        ApplicationErrorReport report = new ApplicationErrorReport();
-        report.packageName = r.info.packageName;
-        report.installerPackageName = r.errorReportReceiver.getPackageName();
-        report.processName = r.processName;
-        report.time = timeMillis;
-        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
-
-        if (r.crashing || r.forceCrashReport) {
-            report.type = ApplicationErrorReport.TYPE_CRASH;
-            report.crashInfo = crashInfo;
-        } else if (r.notResponding) {
-            report.type = ApplicationErrorReport.TYPE_ANR;
-            report.anrInfo = new ApplicationErrorReport.AnrInfo();
-
-            report.anrInfo.activity = r.notRespondingReport.tag;
-            report.anrInfo.cause = r.notRespondingReport.shortMsg;
-            report.anrInfo.info = r.notRespondingReport.longMsg;
-        }
-
-        return report;
-    }
-
     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
         enforceNotIsolatedCaller("getProcessesInErrorState");
         // assume our apps are happy - lazy create the list
@@ -14299,88 +13775,9 @@
 
         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
 
-        if (mProcessCrashTimes.getMap().size() > 0) {
-            boolean printed = false;
-            long now = SystemClock.uptimeMillis();
-            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
-            final int NP = pmap.size();
-            for (int ip=0; ip<NP; ip++) {
-                String pname = pmap.keyAt(ip);
-                SparseArray<Long> uids = pmap.valueAt(ip);
-                final int N = uids.size();
-                for (int i=0; i<N; i++) {
-                    int puid = uids.keyAt(i);
-                    ProcessRecord r = mProcessNames.get(pname, puid);
-                    if (dumpPackage != null && (r == null
-                            || !r.pkgList.containsKey(dumpPackage))) {
-                        continue;
-                    }
-                    if (!printed) {
-                        if (needSep) pw.println();
-                        needSep = true;
-                        pw.println("  Time since processes crashed:");
-                        printed = true;
-                        printedAnything = true;
-                    }
-                    pw.print("    Process "); pw.print(pname);
-                            pw.print(" uid "); pw.print(puid);
-                            pw.print(": last crashed ");
-                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
-                            pw.println(" ago");
-                }
-            }
-        }
-
-        if (mBadProcesses.getMap().size() > 0) {
-            boolean printed = false;
-            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
-            final int NP = pmap.size();
-            for (int ip=0; ip<NP; ip++) {
-                String pname = pmap.keyAt(ip);
-                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
-                final int N = uids.size();
-                for (int i=0; i<N; i++) {
-                    int puid = uids.keyAt(i);
-                    ProcessRecord r = mProcessNames.get(pname, puid);
-                    if (dumpPackage != null && (r == null
-                            || !r.pkgList.containsKey(dumpPackage))) {
-                        continue;
-                    }
-                    if (!printed) {
-                        if (needSep) pw.println();
-                        needSep = true;
-                        pw.println("  Bad processes:");
-                        printedAnything = true;
-                    }
-                    BadProcessInfo info = uids.valueAt(i);
-                    pw.print("    Bad process "); pw.print(pname);
-                            pw.print(" uid "); pw.print(puid);
-                            pw.print(": crashed at time "); pw.println(info.time);
-                    if (info.shortMsg != null) {
-                        pw.print("      Short msg: "); pw.println(info.shortMsg);
-                    }
-                    if (info.longMsg != null) {
-                        pw.print("      Long msg: "); pw.println(info.longMsg);
-                    }
-                    if (info.stack != null) {
-                        pw.println("      Stack:");
-                        int lastPos = 0;
-                        for (int pos=0; pos<info.stack.length(); pos++) {
-                            if (info.stack.charAt(pos) == '\n') {
-                                pw.print("        ");
-                                pw.write(info.stack, lastPos, pos-lastPos);
-                                pw.println();
-                                lastPos = pos+1;
-                            }
-                        }
-                        if (lastPos < info.stack.length()) {
-                            pw.print("        ");
-                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
-                            pw.println();
-                        }
-                    }
-                }
-            }
+        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
+        if (needSep) {
+            printedAnything = true;
         }
 
         if (dumpPackage == null) {
@@ -17462,6 +16859,8 @@
                 case Intent.ACTION_PACKAGE_CHANGED:
                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
+                case Intent.ACTION_PACKAGES_SUSPENDED:
+                case Intent.ACTION_PACKAGES_UNSUSPENDED:
                     // Handle special intents: if this broadcast is from the package
                     // manager about a package being removed, we need to remove all of
                     // its activities from the history stack.
@@ -17542,6 +16941,20 @@
                                 }
                             }
                             break;
+                        case Intent.ACTION_PACKAGES_SUSPENDED:
+                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
+                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
+                                    intent.getAction());
+                            final String[] packageNames = intent.getStringArrayExtra(
+                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
+                            final int userHandle = intent.getIntExtra(
+                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+
+                            synchronized(ActivityManagerService.this) {
+                                mRecentTasks.onPackagesSuspendedChanged(
+                                        packageNames, suspended, userHandle);
+                            }
+                            break;
                     }
                     break;
                 case Intent.ACTION_PACKAGE_ADDED:
@@ -18218,6 +17631,20 @@
         }
     }
 
+    private void updateFontScaleIfNeeded() {
+        final int currentUserId;
+        synchronized(this) {
+            currentUserId = mUserController.getCurrentUserIdLocked();
+        }
+        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
+                FONT_SCALE, 1.0f, currentUserId);
+        if (mConfiguration.fontScale != scaleFactor) {
+            final Configuration configuration = mWindowManager.computeNewConfiguration();
+            configuration.fontScale = scaleFactor;
+            updatePersistentConfiguration(configuration);
+        }
+    }
+
     private void enforceWriteSettingsPermission(String func) {
         int uid = Binder.getCallingUid();
         if (uid == Process.ROOT_UID) {
@@ -18333,7 +17760,7 @@
 
                 // TODO: If our config changes, should we auto dismiss any currently
                 // showing dialogs?
-                mShowDialogs = shouldShowDialogs(newConfig);
+                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
 
                 AttributeCache ac = AttributeCache.instance();
                 if (ac != null) {
@@ -18422,13 +17849,13 @@
      * A thought: SystemUI might also want to get told about this, the Power
      * dialog / global actions also might want different behaviors.
      */
-    private static final boolean shouldShowDialogs(Configuration config) {
+    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
                                    && config.navigation == Configuration.NAVIGATION_NONAV);
         final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
                                     == Configuration.UI_MODE_TYPE_CAR);
-        return inputMethodExists && uiIsNotCarType;
+        return inputMethodExists && uiIsNotCarType && !inVrMode;
     }
 
     @Override
@@ -21013,13 +20440,6 @@
         }
     }
 
-    void stopReportingCrashesLocked(ProcessRecord proc) {
-        if (mAppsNotReportingCrashes == null) {
-            mAppsNotReportingCrashes = new ArraySet<>();
-        }
-        mAppsNotReportingCrashes.add(proc.info.packageName);
-    }
-
     private final class LocalService extends ActivityManagerInternal {
         @Override
         public void onWakefulnessChanged(int wakefulness) {
@@ -21059,6 +20479,15 @@
                 ActivityManagerService.this.onUserStoppedLocked(userId);
             }
         }
+
+        @Override
+        public void onLocalVoiceInteractionStarted(IBinder activity,
+                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
+            synchronized (ActivityManagerService.this) {
+                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
+                        voiceSession, voiceInteractor);
+            }
+        }
     }
 
     private final class SleepTokenImpl extends SleepToken {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index b16bd2b..71008a9 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -54,6 +54,7 @@
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.service.voice.IVoiceInteractionSession;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
@@ -209,6 +210,9 @@
     private int[] mHorizontalSizeConfigurations;
     private int[] mSmallestSizeConfigurations;
 
+    boolean pendingVoiceInteractionStart;   // Waiting for activity-invoked voice session
+    IVoiceInteractionSession voiceSession;  // Voice interaction session for this activity
+
     void dump(PrintWriter pw, String prefix) {
         final long now = SystemClock.uptimeMillis();
         pw.print(prefix); pw.print("packageName="); pw.print(packageName);
@@ -1274,6 +1278,16 @@
         taskDescription = _taskDescription;
     }
 
+    void setVoiceSessionLocked(IVoiceInteractionSession session) {
+        voiceSession = session;
+        pendingVoiceInteractionStart = false;
+    }
+
+    void clearVoiceSessionLocked() {
+        voiceSession = null;
+        pendingVoiceInteractionStart = false;
+    }
+
     void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
         out.attribute(null, ATTR_ID, String.valueOf(createTime));
         out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 10b4ba7..ef8d230 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1567,7 +1567,7 @@
                         behindTranslucentActivity = true;
                     }
                 } else {
-                    if (DEBUG_VISIBILITY || true) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
+                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
                             + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible="
                             + stackInvisible + " behindFullscreenActivity="
                             + behindFullscreenActivity + " mLaunchTaskBehind="
@@ -3041,42 +3041,44 @@
         mService.updateOomAdjLocked();
     }
 
-    final void finishTopRunningActivityLocked(ProcessRecord app, String reason) {
+    final TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) {
         ActivityRecord r = topRunningActivityLocked();
-        if (r != null && r.app == app) {
-            // If the top running activity is from this crashing
-            // process, then terminate it to avoid getting in a loop.
-            Slog.w(TAG, "  Force finishing activity "
-                    + r.intent.getComponent().flattenToShortString());
-            int taskNdx = mTaskHistory.indexOf(r.task);
-            int activityNdx = r.task.mActivities.indexOf(r);
-            finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
-            // Also terminate any activities below it that aren't yet
-            // stopped, to avoid a situation where one will get
-            // re-start our crashing activity once it gets resumed again.
-            --activityNdx;
-            if (activityNdx < 0) {
-                do {
-                    --taskNdx;
-                    if (taskNdx < 0) {
-                        break;
-                    }
-                    activityNdx = mTaskHistory.get(taskNdx).mActivities.size() - 1;
-                } while (activityNdx < 0);
-            }
-            if (activityNdx >= 0) {
-                r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
-                if (r.state == ActivityState.RESUMED
-                        || r.state == ActivityState.PAUSING
-                        || r.state == ActivityState.PAUSED) {
-                    if (!r.isHomeActivity() || mService.mHomeProcess != r.app) {
-                        Slog.w(TAG, "  Force finishing activity "
-                                + r.intent.getComponent().flattenToShortString());
-                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
-                    }
+        TaskRecord finishedTask = null;
+        if (r == null || r.app != app) {
+            return null;
+        }
+        Slog.w(TAG, "  Force finishing activity "
+                + r.intent.getComponent().flattenToShortString());
+        int taskNdx = mTaskHistory.indexOf(r.task);
+        int activityNdx = r.task.mActivities.indexOf(r);
+        finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
+        finishedTask = r.task;
+        // Also terminate any activities below it that aren't yet
+        // stopped, to avoid a situation where one will get
+        // re-start our crashing activity once it gets resumed again.
+        --activityNdx;
+        if (activityNdx < 0) {
+            do {
+                --taskNdx;
+                if (taskNdx < 0) {
+                    break;
+                }
+                activityNdx = mTaskHistory.get(taskNdx).mActivities.size() - 1;
+            } while (activityNdx < 0);
+        }
+        if (activityNdx >= 0) {
+            r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
+            if (r.state == ActivityState.RESUMED
+                    || r.state == ActivityState.PAUSING
+                    || r.state == ActivityState.PAUSED) {
+                if (!r.isHomeActivity() || mService.mHomeProcess != r.app) {
+                    Slog.w(TAG, "  Force finishing activity "
+                            + r.intent.getComponent().flattenToShortString());
+                    finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
                 }
             }
         }
+        return finishedTask;
     }
 
     final void finishVoiceTask(IVoiceInteractionSession session) {
@@ -3093,8 +3095,29 @@
                         didOne = true;
                     }
                 }
+            } else {
+                // Check if any of the activities are using voice
+                for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
+                    ActivityRecord r = tr.mActivities.get(activityNdx);
+                    if (r.voiceSession != null
+                            && r.voiceSession.asBinder() == sessionBinder) {
+                        // Inform of cancellation
+                        r.clearVoiceSessionLocked();
+                        try {
+                            r.app.thread.scheduleLocalVoiceInteractionStarted((IBinder) r.appToken,
+                                    null);
+                        } catch (RemoteException re) {
+                            // Ok
+                        }
+                        // TODO: VI This is redundant in some cases
+                        mService.finishRunningVoiceLocked();
+                        break;
+                    }
+                }
             }
         }
+        Slog.d(TAG, "ActivityStack.finishVoiceTask()");
+
         if (didOne) {
             mService.updateOomAdjLocked();
         }
@@ -4686,6 +4709,7 @@
         updateTaskMovement(task, true);
 
         if (!moving && task.mActivities.isEmpty()) {
+            // TODO: VI what about activity?
             final boolean isVoiceSession = task.voiceSession != null;
             if (isVoiceSession) {
                 try {
@@ -4790,6 +4814,7 @@
 
     void addConfigOverride(ActivityRecord r, TaskRecord task) {
         final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds();
+        // TODO: VI deal with activity
         mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                 r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                 (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId, r.info.configChanges,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 1fc674b..8db2f8f 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1668,15 +1668,21 @@
         return false;
     }
 
-    void finishTopRunningActivityLocked(ProcessRecord app, String reason) {
+    TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) {
+        TaskRecord finishedTask = null;
+        ActivityStack focusedStack = getFocusedStack();
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
             final int numStacks = stacks.size();
             for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
                 final ActivityStack stack = stacks.get(stackNdx);
-                stack.finishTopRunningActivityLocked(app, reason);
+                TaskRecord t = stack.finishTopRunningActivityLocked(app, reason);
+                if (stack == focusedStack || finishedTask == null) {
+                    finishedTask = t;
+                }
             }
         }
+        return finishedTask;
     }
 
     void finishVoiceTask(IVoiceInteractionSession session) {
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
new file mode 100644
index 0000000..1ed749f
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -0,0 +1,180 @@
+package com.android.server.am;
+
+import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
+import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
+import static android.app.PendingIntent.FLAG_IMMUTABLE;
+import static android.app.PendingIntent.FLAG_ONE_SHOT;
+import static android.content.Context.KEYGUARD_SERVICE;
+import static android.content.Intent.EXTRA_INTENT;
+import static android.content.Intent.EXTRA_PACKAGE_NAME;
+import static android.content.Intent.EXTRA_TASK_ID;
+import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
+
+import android.app.KeyguardManager;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
+import android.os.Binder;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import com.android.internal.app.UnlaunchableAppActivity;
+
+/**
+ * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked}
+ * It's initialized
+ */
+class ActivityStartInterceptor {
+
+    private final ActivityManagerService mService;
+    private UserManager mUserManager;
+    private final ActivityStackSupervisor mSupervisor;
+
+    /*
+     * Per-intent states loaded from ActivityStarter than shouldn't be changed by any
+     * interception routines.
+     */
+    private int mRealCallingPid;
+    private int mRealCallingUid;
+    private int mUserId;
+    private int mStartFlags;
+    private String mCallingPackage;
+
+    /*
+     * Per-intent states that were load from ActivityStarter and are subject to modifications
+     * by the interception routines. After calling {@link #intercept} the caller should assign
+     * these values back to {@link ActivityStarter#startActivityLocked}'s local variables.
+     */
+    Intent mIntent;
+    int mCallingPid;
+    int mCallingUid;
+    ResolveInfo mRInfo;
+    ActivityInfo mAInfo;
+    String mResolvedType;
+    TaskRecord mInTask;
+
+    ActivityStartInterceptor(ActivityManagerService service, ActivityStackSupervisor supervisor) {
+        mService = service;
+        mSupervisor = supervisor;
+    }
+
+    void setStates(int userId, int realCallingPid, int realCallingUid, int startFlags,
+            String callingPackage) {
+        mRealCallingPid = realCallingPid;
+        mRealCallingUid = realCallingUid;
+        mUserId = userId;
+        mStartFlags = startFlags;
+        mCallingPackage = callingPackage;
+    }
+
+    void intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType,
+            TaskRecord inTask, int callingPid, int callingUid) {
+        mUserManager = UserManager.get(mService.mContext);
+        mIntent = intent;
+        mCallingPid = callingPid;
+        mCallingUid = callingUid;
+        mRInfo = rInfo;
+        mAInfo = aInfo;
+        mResolvedType = resolvedType;
+        mInTask = inTask;
+        interceptQuietProfileIfNeeded();
+        interceptSuspendPackageIfNeed();
+        interceptWorkProfileChallengeIfNeeded();
+    }
+
+    private void interceptQuietProfileIfNeeded() {
+        // Do not intercept if the user has not turned off the profile
+        if (!mUserManager.isQuietModeEnabled(UserHandle.of(mUserId))) {
+            return;
+        }
+        mIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent(mUserId);
+        mCallingPid = mRealCallingPid;
+        mCallingUid = mRealCallingUid;
+        mResolvedType = null;
+
+        final UserInfo parent = mUserManager.getProfileParent(mUserId);
+        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+        mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags,
+                null /*profilerInfo*/);
+    }
+
+    private void interceptSuspendPackageIfNeed() {
+        // Do not intercept if the admin did not suspend the package
+        if (mAInfo == null || mAInfo.applicationInfo == null ||
+                (mAInfo.applicationInfo.flags & FLAG_SUSPENDED) == 0) {
+            return;
+        }
+        mIntent = UnlaunchableAppActivity.createPackageSuspendedDialogIntent(mAInfo.packageName,
+                mUserId);
+        mCallingPid = mRealCallingPid;
+        mCallingUid = mRealCallingUid;
+        mResolvedType = null;
+
+        final UserInfo parent = mUserManager.getProfileParent(mUserId);
+        if (parent != null) {
+            mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+        } else {
+            mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId);
+        }
+        mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags,
+                null /*profilerInfo*/);
+    }
+
+    private void interceptWorkProfileChallengeIfNeeded() {
+        final Intent interceptingIntent = interceptWithConfirmCredentialsIfNeeded(mIntent,
+                mResolvedType, mAInfo, mCallingPackage, mUserId);
+        if (interceptingIntent == null) {
+            return;
+        }
+        mIntent = interceptingIntent;
+        mCallingPid = mRealCallingPid;
+        mCallingUid = mRealCallingUid;
+        mResolvedType = null;
+        // If we are intercepting and there was a task, convert it into an extra for the
+        // ConfirmCredentials intent and unassign it, as otherwise the task will move to
+        // front even if ConfirmCredentials is cancelled.
+        if (mInTask != null) {
+            mIntent.putExtra(EXTRA_TASK_ID, mInTask.taskId);
+            mInTask = null;
+        }
+
+        final UserInfo parent = mUserManager.getProfileParent(mUserId);
+        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+        mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags,
+                null /*profilerInfo*/);
+    }
+
+    /**
+     * Creates an intent to intercept the current activity start with Confirm Credentials if needed.
+     *
+     * @return The intercepting intent if needed.
+     */
+    private Intent interceptWithConfirmCredentialsIfNeeded(Intent intent, String resolvedType,
+            ActivityInfo aInfo, String callingPackage, int userId) {
+        if (!mService.mUserController.shouldConfirmCredentials(userId)) {
+            return null;
+        }
+        final IIntentSender target = mService.getIntentSenderLocked(
+                INTENT_SENDER_ACTIVITY, callingPackage,
+                Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent },
+                new String[]{ resolvedType },
+                FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT | FLAG_IMMUTABLE, null);
+        final int flags = intent.getFlags();
+        final KeyguardManager km = (KeyguardManager) mService.mContext
+                .getSystemService(KEYGUARD_SERVICE);
+        final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, userId);
+        if (newIntent == null) {
+            return null;
+        }
+        newIntent.setFlags(flags | FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        newIntent.putExtra(EXTRA_PACKAGE_NAME, aInfo.packageName);
+        newIntent.putExtra(EXTRA_INTENT, new IntentSender(target));
+        return newIntent;
+    }
+
+}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index d847824..7b7359f 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1,11 +1,9 @@
 package com.android.server.am;
 
 import static android.app.Activity.RESULT_CANCELED;
-import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
 import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
 import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
-import static android.app.ActivityManager.START_PERMISSION_DENIED;
 import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
 import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
 import static android.app.ActivityManager.START_SUCCESS;
@@ -17,16 +15,8 @@
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
-import static android.app.PendingIntent.FLAG_IMMUTABLE;
-import static android.app.PendingIntent.FLAG_ONE_SHOT;
-import static android.content.Context.KEYGUARD_SERVICE;
-import static android.content.Intent.EXTRA_INTENT;
-import static android.content.Intent.EXTRA_PACKAGE_NAME;
-import static android.content.Intent.EXTRA_TASK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
-import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_TO_SIDE;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
@@ -43,7 +33,6 @@
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
-import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
@@ -76,7 +65,6 @@
 import android.app.IActivityContainer;
 import android.app.IActivityManager;
 import android.app.IApplicationThread;
-import android.app.KeyguardManager;
 import android.app.PendingIntent;
 import android.app.ProfilerInfo;
 import android.content.ComponentName;
@@ -86,7 +74,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Binder;
@@ -96,7 +83,6 @@
 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;
@@ -124,6 +110,7 @@
 
     private final ActivityManagerService mService;
     private final ActivityStackSupervisor mSupervisor;
+    private ActivityStartInterceptor mInterceptor;
     private WindowManagerService mWindowManager;
 
     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches = new ArrayList<>();
@@ -204,6 +191,7 @@
     ActivityStarter(ActivityManagerService service, ActivityStackSupervisor supervisor) {
         mService = service;
         mSupervisor = supervisor;
+        mInterceptor = new ActivityStartInterceptor(mService, mSupervisor);
     }
 
     final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
@@ -230,17 +218,6 @@
             }
         }
 
-        if (aInfo != null) {
-            if ((aInfo.applicationInfo.flags & FLAG_SUSPENDED) != 0) {
-                Slog.w(TAG, "Application \"" + aInfo.applicationInfo.packageName
-                        + "\" is suspended. Refusing to start: " + intent.toString());
-                // TODO: show a dialog/activity informing the user that the application is suspended 
-                // and redirect the launch to it. Do not return START_PERMISSION_DENIED because 
-                // it is wrong.
-                err = ActivityManager.START_PERMISSION_DENIED;
-            }
-        }
-
         final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
 
         if (err == ActivityManager.START_SUCCESS) {
@@ -381,26 +358,15 @@
             }
         }
 
-        final Intent interceptingIntent = interceptWithConfirmCredentialsIfNeeded(intent,
-                resolvedType, aInfo, callingPackage, userId);
-        if (interceptingIntent != null) {
-            intent = interceptingIntent;
-            callingPid = realCallingPid;
-            callingUid = realCallingUid;
-            resolvedType = null;
-            // If we are intercepting and there was a task, convert it into an extra for the
-            // ConfirmCredentials intent and unassign it, as otherwise the task will move to
-            // front even if ConfirmCredentials is cancelled.
-            if (inTask != null) {
-                intent.putExtra(EXTRA_TASK_ID, inTask.taskId);
-                inTask = null;
-            }
-
-            final UserInfo parent = UserManager.get(mService.mContext).getProfileParent(userId);
-            rInfo = mSupervisor.resolveIntent(intent, resolvedType, parent.id);
-            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
-                    null /*profilerInfo*/);
-        }
+        mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
+        mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid);
+        intent = mInterceptor.mIntent;
+        rInfo = mInterceptor.mRInfo;
+        aInfo = mInterceptor.mAInfo;
+        resolvedType = mInterceptor.mResolvedType;
+        inTask = mInterceptor.mInTask;
+        callingPid = mInterceptor.mCallingPid;
+        callingUid = mInterceptor.mCallingUid;
 
         if (abort) {
             if (resultRecord != null) {
@@ -538,46 +504,45 @@
 
         err = startActivityUnchecked(
                 r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask);
-
-        if (err < 0) {
-            // If someone asked to have the keyguard dismissed on the next
-            // activity start, but we are not actually doing an activity
-            // switch...  just dismiss the keyguard now, because we
-            // probably want to see whatever is behind it.
-            mSupervisor.notifyActivityDrawnForKeyguard();
-        } else {
-            launchRecentsAppIfNeeded(stack);
-        }
-
+        postStartActivityUncheckedProcessing(r, err, stack.mStackId);
         return err;
     }
 
-    /**
-     * Creates an intent to intercept the current activity start with Confirm Credentials if needed.
-     *
-     * @return The intercepting intent if needed.
-     */
-    private Intent interceptWithConfirmCredentialsIfNeeded(Intent intent, String resolvedType,
-            ActivityInfo aInfo, String callingPackage, int userId) {
-        if (!mService.mUserController.shouldConfirmCredentials(userId)) {
-            return null;
+    void postStartActivityUncheckedProcessing(
+            ActivityRecord r, int result, int prevFocusedStackId) {
+
+        if (result < START_SUCCESS) {
+            // If someone asked to have the keyguard dismissed on the next activity start,
+            // but we are not actually doing an activity switch...  just dismiss the keyguard now,
+            // because we probably want to see whatever is behind it.
+            mSupervisor.notifyActivityDrawnForKeyguard();
+            return;
         }
-        final IIntentSender target = mService.getIntentSenderLocked(
-                INTENT_SENDER_ACTIVITY, callingPackage,
-                Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent },
-                new String[]{ resolvedType },
-                FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT | FLAG_IMMUTABLE, null);
-        final int flags = intent.getFlags();
-        final KeyguardManager km = (KeyguardManager) mService.mContext
-                .getSystemService(KEYGUARD_SERVICE);
-        final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, userId);
-        if (newIntent == null) {
-            return null;
+
+        int startedActivityStackId = INVALID_STACK_ID;
+        if (r.task != null && r.task.stack != null) {
+            startedActivityStackId = r.task.stack.mStackId;
+        } else if (mTargetStack != null) {
+            startedActivityStackId = mTargetStack.mStackId;
         }
-        newIntent.setFlags(flags | FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        newIntent.putExtra(EXTRA_PACKAGE_NAME, aInfo.packageName);
-        newIntent.putExtra(EXTRA_INTENT, new IntentSender(target));
-        return newIntent;
+
+        if (startedActivityStackId == DOCKED_STACK_ID && prevFocusedStackId == HOME_STACK_ID) {
+            // We launch an activity while being in home stack, which means either launcher or
+            // recents into docked stack. We don't want the launched activity to be alone in a
+            // docked stack, so we want to immediately launch recents too.
+            if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch.");
+            mWindowManager.showRecentApps();
+            return;
+        }
+
+        if (startedActivityStackId == PINNED_STACK_ID
+                && (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP)) {
+            // The activity was already running in the pinned stack so it wasn't started, but either
+            // brought to the front or the new intent was delivered to it since it was already in
+            // front. Notify anyone interested in this piece of information.
+            mService.notifyPinnedActivityRestartAttemptLocked();
+            return;
+        }
     }
 
     void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
@@ -1047,17 +1012,6 @@
         return START_SUCCESS;
     }
 
-    private void launchRecentsAppIfNeeded(ActivityStack topStack) {
-        if (topStack.mStackId == HOME_STACK_ID && mTargetStack != null
-                && mTargetStack.mStackId == DOCKED_STACK_ID) {
-            // We launch an activity while being in home stack, which means either launcher or
-            // recents into docked stack. We don't want the launched activity to be alone in a
-            // docked stack, so we want to immediately launch recents too.
-            if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch.");
-            mWindowManager.showRecentApps();
-        }
-    }
-
     private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
             boolean doResume, int startFlags, ActivityRecord sourceRecord,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
@@ -1619,11 +1573,13 @@
 
     final void doPendingActivityLaunchesLocked(boolean doResume) {
         while (!mPendingActivityLaunches.isEmpty()) {
-            PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
-
+            final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
+            final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
             try {
-                startActivityUnchecked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
-                        doResume && mPendingActivityLaunches.isEmpty(), null, null);
+                final int result = startActivityUnchecked(
+                        pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);
+                postStartActivityUncheckedProcessing(
+                        pal.r, result, mSupervisor.mFocusedStack.mStackId);
             } catch (Exception e) {
                 Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
                 pal.sendErrorResult(e.getMessage());
diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java
index c87eae0..b746a4b 100644
--- a/services/core/java/com/android/server/am/AppErrorDialog.java
+++ b/services/core/java/com/android/server/am/AppErrorDialog.java
@@ -16,73 +16,74 @@
 
 package com.android.server.am;
 
+import android.app.ActivityManagerInternal;
+import android.app.ActivityOptions;
 import android.content.Context;
-import android.content.DialogInterface;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.widget.CheckBox;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-final class AppErrorDialog extends BaseErrorDialog {
+import java.util.List;
+
+import static com.android.server.am.ActivityManagerService.IS_USER_BUILD;
+
+final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListener {
     private final ActivityManagerService mService;
     private final AppErrorResult mResult;
     private final ProcessRecord mProc;
+    private final boolean mRepeating;
+
     private CharSequence mName;
 
     // Event 'what' codes
-    static final int FORCE_QUIT = 0;
-    static final int FORCE_QUIT_AND_REPORT = 1;
+    static final int FORCE_QUIT = 1;
+    static final int FORCE_QUIT_AND_REPORT = 2;
+    static final int RESTART = 3;
+    static final int RESET = 4;
+    static final int MUTE = 5;
 
     // 5-minute timeout, then we automatically dismiss the crash dialog
     static final long DISMISS_TIMEOUT = 1000 * 60 * 5;
-    
-    public AppErrorDialog(Context context, ActivityManagerService service,
-            AppErrorResult result, ProcessRecord app) {
-        super(context);
 
+    public AppErrorDialog(Context context, ActivityManagerService service, Data data) {
+        super(context);
         Resources res = context.getResources();
 
         mService = service;
-        mProc = app;
-        mResult = result;
-        if ((app.pkgList.size() == 1) &&
-                (mName = context.getPackageManager().getApplicationLabel(app.info)) != null) {
-            setMessage(res.getString(
-                    com.android.internal.R.string.aerr_application,
-                    mName.toString(), app.info.processName));
+        mProc = data.proc;
+        mResult = data.result;
+        mRepeating = data.repeating;
+        if ((mProc.pkgList.size() == 1) &&
+                (mName = context.getPackageManager().getApplicationLabel(mProc.info)) != null) {
+            setTitle(res.getString(
+                    mRepeating ? com.android.internal.R.string.aerr_application_repeated
+                            : com.android.internal.R.string.aerr_application,
+                    mName.toString(), mProc.info.processName));
         } else {
-            mName = app.processName;
-            setMessage(res.getString(
-                    com.android.internal.R.string.aerr_process,
+            mName = mProc.processName;
+            setTitle(res.getString(
+                    mRepeating ? com.android.internal.R.string.aerr_process_repeated
+                            : com.android.internal.R.string.aerr_process,
                     mName.toString()));
         }
 
         setCancelable(false);
 
-        setButton(DialogInterface.BUTTON_POSITIVE,
-                res.getText(com.android.internal.R.string.force_close),
-                mHandler.obtainMessage(FORCE_QUIT));
-
-        if (app.errorReportReceiver != null) {
-            setButton(DialogInterface.BUTTON_NEGATIVE,
-                    res.getText(com.android.internal.R.string.report),
-                    mHandler.obtainMessage(FORCE_QUIT_AND_REPORT));
-        }
-
-        setTitle(res.getText(com.android.internal.R.string.aerr_title));
         WindowManager.LayoutParams attrs = getWindow().getAttributes();
-        attrs.setTitle("Application Error: " + app.info.processName);
+        attrs.setTitle("Application Error: " + mProc.info.processName);
         attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR
                 | WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
         getWindow().setAttributes(attrs);
-        if (app.persistent) {
+        if (mProc.persistent) {
             getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
         }
 
@@ -95,38 +96,44 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        if (!ActivityManagerService.IS_USER_BUILD) {
-            FrameLayout frame = (FrameLayout) findViewById(android.R.id.custom);
-            Context context = getContext();
-            LayoutInflater.from(context).inflate(
-                    com.android.internal.R.layout.app_error_dialog_dont_show_again, frame, true);
-            ((TextView) frame.findViewById(com.android.internal.R.id.text)).setText(
-                    context.getResources().getString(
-                            com.android.internal.R.string.aerr_process_silence,
-                            mName.toString()));
-            findViewById(com.android.internal.R.id.customPanel).setVisibility(View.VISIBLE);
-        }
+        final FrameLayout frame = (FrameLayout) findViewById(android.R.id.custom);
+        final Context context = getContext();
+        LayoutInflater.from(context).inflate(
+                com.android.internal.R.layout.app_error_dialog, frame, true);
+
+        final TextView restart = (TextView) findViewById(com.android.internal.R.id.aerr_restart);
+        restart.setOnClickListener(this);
+        restart.setVisibility(!mRepeating ? View.VISIBLE : View.GONE);
+        final TextView reset = (TextView) findViewById(com.android.internal.R.id.aerr_reset);
+        reset.setOnClickListener(this);
+        reset.setVisibility(mRepeating ? View.VISIBLE : View.GONE);
+        final TextView report = (TextView) findViewById(com.android.internal.R.id.aerr_report);
+        report.setOnClickListener(this);
+        final boolean hasReceiver = mProc.errorReportReceiver != null;
+        report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
+        final TextView close = (TextView) findViewById(com.android.internal.R.id.aerr_close);
+        close.setOnClickListener(this);
+        final TextView mute = (TextView) findViewById(com.android.internal.R.id.aerr_mute);
+        mute.setOnClickListener(this);
+        mute.setVisibility(!IS_USER_BUILD ? View.VISIBLE : View.GONE);
+
+        findViewById(com.android.internal.R.id.customPanel).setVisibility(View.VISIBLE);
     }
 
     private final Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
-            View view = findViewById(com.android.internal.R.id.checkbox);
-            final boolean stopReporting = view != null && ((CheckBox) view).isChecked();
+            final int result = msg.what;
+
             synchronized (mService) {
                 if (mProc != null && mProc.crashDialog == AppErrorDialog.this) {
                     mProc.crashDialog = null;
                 }
-                if (stopReporting) {
-                    mService.stopReportingCrashesLocked(mProc);
-                }
             }
-            mResult.set(msg.what);
+            mResult.set(result);
 
             // Make sure we don't have time timeout still hanging around.
             removeMessages(FORCE_QUIT);
 
-            // If this is a timeout we won't be automatically closed, so go
-            // ahead and explicitly dismiss ourselves just in case.
             dismiss();
         }
     };
@@ -139,4 +146,34 @@
         }
         super.dismiss();
     }
+
+    @Override
+    public void onClick(View v) {
+        switch (v.getId()) {
+            case com.android.internal.R.id.aerr_restart:
+                mHandler.obtainMessage(RESTART).sendToTarget();
+                break;
+            case com.android.internal.R.id.aerr_reset:
+                mHandler.obtainMessage(RESET).sendToTarget();
+                break;
+            case com.android.internal.R.id.aerr_report:
+                mHandler.obtainMessage(FORCE_QUIT_AND_REPORT).sendToTarget();
+                break;
+            case com.android.internal.R.id.aerr_close:
+                mHandler.obtainMessage(FORCE_QUIT).sendToTarget();
+                break;
+            case com.android.internal.R.id.aerr_mute:
+                mHandler.obtainMessage(MUTE).sendToTarget();
+                break;
+            default:
+                break;
+        }
+    }
+
+    static class Data {
+        AppErrorResult result;
+        TaskRecord task;
+        boolean repeating;
+        ProcessRecord proc;
+    }
 }
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
new file mode 100644
index 0000000..58d9f45
--- /dev/null
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -0,0 +1,964 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 com.android.internal.app.ProcessMap;
+import com.android.internal.os.ProcessCpuTracker;
+import com.android.server.Watchdog;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.ActivityThread;
+import android.app.AppOpsManager;
+import android.app.ApplicationErrorReport;
+import android.app.Dialog;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.EventLog;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TimeUtils;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.concurrent.Semaphore;
+
+import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
+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.MY_PID;
+import static com.android.server.am.ActivityManagerService.SYSTEM_DEBUGGABLE;
+
+/**
+ * Controls error conditions in applications.
+ */
+class AppErrors {
+
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppErrors" : TAG_AM;
+
+    private final ActivityManagerService mService;
+    private final Context mContext;
+
+    private ArraySet<String> mAppsNotReportingCrashes;
+
+    /**
+     * The last time that various processes have crashed since they were last explicitly started.
+     */
+    private final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<>();
+
+    /**
+     * The last time that various processes have crashed (not reset even when explicitly started).
+     */
+    private final ProcessMap<Long> mProcessCrashTimesPersistent = new ProcessMap<>();
+
+    /**
+     * Set of applications that we consider to be bad, and will reject
+     * incoming broadcasts from (which the user has no control over).
+     * Processes are added to this set when they have crashed twice within
+     * a minimum amount of time; they are removed from it when they are
+     * later restarted (hopefully due to some user action).  The value is the
+     * time it was added to the list.
+     */
+    private final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>();
+
+
+    AppErrors(Context context, ActivityManagerService service) {
+        mService = service;
+        mContext = context;
+    }
+
+    boolean dumpLocked(FileDescriptor fd, PrintWriter pw, boolean needSep,
+            String dumpPackage) {
+        if (!mProcessCrashTimes.getMap().isEmpty()) {
+            boolean printed = false;
+            final long now = SystemClock.uptimeMillis();
+            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
+            final int processCount = pmap.size();
+            for (int ip = 0; ip < processCount; ip++) {
+                final String pname = pmap.keyAt(ip);
+                final SparseArray<Long> uids = pmap.valueAt(ip);
+                final int uidCount = uids.size();
+                for (int i = 0; i < uidCount; i++) {
+                    final int puid = uids.keyAt(i);
+                    final ProcessRecord r = mService.mProcessNames.get(pname, puid);
+                    if (dumpPackage != null && (r == null
+                            || !r.pkgList.containsKey(dumpPackage))) {
+                        continue;
+                    }
+                    if (!printed) {
+                        if (needSep) pw.println();
+                        needSep = true;
+                        pw.println("  Time since processes crashed:");
+                        printed = true;
+                    }
+                    pw.print("    Process "); pw.print(pname);
+                    pw.print(" uid "); pw.print(puid);
+                    pw.print(": last crashed ");
+                    TimeUtils.formatDuration(now-uids.valueAt(i), pw);
+                    pw.println(" ago");
+                }
+            }
+        }
+
+        if (!mBadProcesses.getMap().isEmpty()) {
+            boolean printed = false;
+            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
+            final int processCount = pmap.size();
+            for (int ip = 0; ip < processCount; ip++) {
+                final String pname = pmap.keyAt(ip);
+                final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
+                final int uidCount = uids.size();
+                for (int i = 0; i < uidCount; i++) {
+                    final int puid = uids.keyAt(i);
+                    final ProcessRecord r = mService.mProcessNames.get(pname, puid);
+                    if (dumpPackage != null && (r == null
+                            || !r.pkgList.containsKey(dumpPackage))) {
+                        continue;
+                    }
+                    if (!printed) {
+                        if (needSep) pw.println();
+                        needSep = true;
+                        pw.println("  Bad processes:");
+                        printed = true;
+                    }
+                    final BadProcessInfo info = uids.valueAt(i);
+                    pw.print("    Bad process "); pw.print(pname);
+                    pw.print(" uid "); pw.print(puid);
+                    pw.print(": crashed at time "); pw.println(info.time);
+                    if (info.shortMsg != null) {
+                        pw.print("      Short msg: "); pw.println(info.shortMsg);
+                    }
+                    if (info.longMsg != null) {
+                        pw.print("      Long msg: "); pw.println(info.longMsg);
+                    }
+                    if (info.stack != null) {
+                        pw.println("      Stack:");
+                        int lastPos = 0;
+                        for (int pos = 0; pos < info.stack.length(); pos++) {
+                            if (info.stack.charAt(pos) == '\n') {
+                                pw.print("        ");
+                                pw.write(info.stack, lastPos, pos-lastPos);
+                                pw.println();
+                                lastPos = pos+1;
+                            }
+                        }
+                        if (lastPos < info.stack.length()) {
+                            pw.print("        ");
+                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
+                            pw.println();
+                        }
+                    }
+                }
+            }
+        }
+        return needSep;
+    }
+
+    boolean isBadProcessLocked(ApplicationInfo info) {
+        return mBadProcesses.get(info.processName, info.uid) != null;
+    }
+
+    void clearBadProcessLocked(ApplicationInfo info) {
+        mBadProcesses.remove(info.processName, info.uid);
+    }
+
+    void resetProcessCrashTimeLocked(ApplicationInfo info) {
+        mProcessCrashTimes.remove(info.processName, info.uid);
+    }
+
+    void resetProcessCrashTimeLocked(boolean resetEntireUser, int appId, int userId) {
+        final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
+        for (int ip = pmap.size() - 1; ip >= 0; ip--) {
+            SparseArray<Long> ba = pmap.valueAt(ip);
+            for (int i = ba.size() - 1; i >= 0; i--) {
+                boolean remove = false;
+                final int entUid = ba.keyAt(i);
+                if (!resetEntireUser) {
+                    if (userId == UserHandle.USER_ALL) {
+                        if (UserHandle.getAppId(entUid) == appId) {
+                            remove = true;
+                        }
+                    } else {
+                        if (entUid == UserHandle.getUid(userId, appId)) {
+                            remove = true;
+                        }
+                    }
+                } else if (UserHandle.getUserId(entUid) == userId) {
+                    remove = true;
+                }
+                if (remove) {
+                    ba.removeAt(i);
+                }
+            }
+            if (ba.size() == 0) {
+                pmap.removeAt(ip);
+            }
+        }
+    }
+
+    void loadAppsNotReportingCrashesFromConfigLocked(String appsNotReportingCrashesConfig) {
+        if (appsNotReportingCrashesConfig != null) {
+            final String[] split = appsNotReportingCrashesConfig.split(",");
+            if (split.length > 0) {
+                mAppsNotReportingCrashes = new ArraySet<>();
+                Collections.addAll(mAppsNotReportingCrashes, split);
+            }
+        }
+    }
+
+    void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) {
+        app.crashing = false;
+        app.crashingReport = null;
+        app.notResponding = false;
+        app.notRespondingReport = null;
+        if (app.anrDialog == fromDialog) {
+            app.anrDialog = null;
+        }
+        if (app.waitDialog == fromDialog) {
+            app.waitDialog = null;
+        }
+        if (app.pid > 0 && app.pid != MY_PID) {
+            handleAppCrashLocked(app, "user-terminated" /*reason*/,
+                    null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
+            app.kill("user request after error", true);
+        }
+    }
+
+    void scheduleAppCrashLocked(int uid, int initialPid, String packageName,
+            String message) {
+        ProcessRecord proc = null;
+
+        // Figure out which process to kill.  We don't trust that initialPid
+        // still has any relation to current pids, so must scan through the
+        // list.
+
+        synchronized (mService.mPidsSelfLocked) {
+            for (int i=0; i<mService.mPidsSelfLocked.size(); i++) {
+                ProcessRecord p = mService.mPidsSelfLocked.valueAt(i);
+                if (p.uid != uid) {
+                    continue;
+                }
+                if (p.pid == initialPid) {
+                    proc = p;
+                    break;
+                }
+                if (p.pkgList.containsKey(packageName)) {
+                    proc = p;
+                }
+            }
+        }
+
+        if (proc == null) {
+            Slog.w(TAG, "crashApplication: nothing for uid=" + uid
+                    + " initialPid=" + initialPid
+                    + " packageName=" + packageName);
+            return;
+        }
+
+        if (proc.thread != null) {
+            if (proc.pid == Process.myPid()) {
+                Log.w(TAG, "crashApplication: trying to crash self!");
+                return;
+            }
+            long ident = Binder.clearCallingIdentity();
+            try {
+                proc.thread.scheduleCrash(message);
+            } catch (RemoteException e) {
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    /**
+     * Bring up the "unexpected error" dialog box for a crashing app.
+     * Deal with edge cases (intercepts from instrumented applications,
+     * ActivityController, error intent receivers, that sort of thing).
+     * @param r the application crashing
+     * @param crashInfo describing the failure
+     */
+    void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
+        long timeMillis = System.currentTimeMillis();
+        String shortMsg = crashInfo.exceptionClassName;
+        String longMsg = crashInfo.exceptionMessage;
+        String stackTrace = crashInfo.stackTrace;
+        if (shortMsg != null && longMsg != null) {
+            longMsg = shortMsg + ": " + longMsg;
+        } else if (shortMsg != null) {
+            longMsg = shortMsg;
+        }
+
+        AppErrorResult result = new AppErrorResult();
+        TaskRecord task;
+        synchronized (mService) {
+            if (mService.mController != null) {
+                try {
+                    String name = r != null ? r.processName : null;
+                    int pid = r != null ? r.pid : Binder.getCallingPid();
+                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
+                    if (!mService.mController.appCrashed(name, pid,
+                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
+                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
+                                && "Native crash".equals(crashInfo.exceptionClassName)) {
+                            Slog.w(TAG, "Skip killing native crashed app " + name
+                                    + "(" + pid + ") during testing");
+                        } else {
+                            Slog.w(TAG, "Force-killing crashed app " + name
+                                    + " at watcher's request");
+                            if (r != null) {
+                                r.kill("crash", true);
+                            } else {
+                                // Huh.
+                                Process.killProcess(pid);
+                                ActivityManagerService.killProcessGroup(uid, pid);
+                            }
+                        }
+                        return;
+                    }
+                } catch (RemoteException e) {
+                    mService.mController = null;
+                    Watchdog.getInstance().setActivityController(null);
+                }
+            }
+
+            final long origId = Binder.clearCallingIdentity();
+
+            // If this process is running instrumentation, finish it.
+            if (r != null && r.instrumentationClass != null) {
+                Slog.w(TAG, "Error in app " + r.processName
+                        + " running instrumentation " + r.instrumentationClass + ":");
+                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
+                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
+                Bundle info = new Bundle();
+                info.putString("shortMsg", shortMsg);
+                info.putString("longMsg", longMsg);
+                mService.finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
+                Binder.restoreCallingIdentity(origId);
+                return;
+            }
+
+            // Log crash in battery stats.
+            if (r != null) {
+                mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
+            }
+
+            AppErrorDialog.Data data = new AppErrorDialog.Data();
+            data.result = result;
+            data.proc = r;
+
+            // If we can't identify the process or it's already exceeded its crash quota,
+            // quit right away without showing a crash dialog.
+            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
+                Binder.restoreCallingIdentity(origId);
+                return;
+            }
+
+            Message msg = Message.obtain();
+            msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
+
+            task = data.task;
+            msg.obj = data;
+            mService.mUiHandler.sendMessage(msg);
+
+            Binder.restoreCallingIdentity(origId);
+        }
+
+        int res = result.get();
+
+        Intent appErrorIntent = null;
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            if (res == AppErrorDialog.RESET) {
+                String[] packageList = r.getPackageList();
+                if (packageList != null) {
+                    PackageManager pm = mContext.getPackageManager();
+                    final Semaphore s = new Semaphore(0);
+                    for (int i = 0; i < packageList.length; i++) {
+                        if (i < packageList.length - 1) {
+                            pm.deleteApplicationCacheFiles(packageList[i], null);
+                        } else {
+                            pm.deleteApplicationCacheFiles(packageList[i],
+                                    new IPackageDataObserver.Stub() {
+                                        @Override
+                                        public void onRemoveCompleted(String packageName,
+                                                boolean succeeded) {
+                                            s.release();
+                                        }
+                                    });
+
+                            // Wait until cache has been cleared before we restart.
+                            try {
+                                s.acquire();
+                            } catch (InterruptedException e) {
+                            }
+                        }
+                    }
+                }
+                // If there was nothing to reset, just restart;
+                res = AppErrorDialog.RESTART;
+            }
+            synchronized (mService) {
+                if (res == AppErrorDialog.MUTE) {
+                    stopReportingCrashesLocked(r);
+                }
+                if (res == AppErrorDialog.RESTART) {
+                    mService.removeProcessLocked(r, false, true, "crash");
+                    if (task != null) {
+                        try {
+                            mService.startActivityFromRecents(task.taskId,
+                                    ActivityOptions.makeBasic().toBundle());
+                        } catch (IllegalArgumentException e) {
+                            // Hmm, that didn't work, app might have crashed before creating a
+                            // recents entry. Let's see if we have a safe-to-restart intent.
+                            if (task.intent.getCategories().contains(
+                                    Intent.CATEGORY_LAUNCHER)) {
+                                mService.startActivityInPackage(task.mCallingUid,
+                                        task.mCallingPackage, task.intent,
+                                        null, null, null, 0, 0,
+                                        ActivityOptions.makeBasic().toBundle(),
+                                        task.userId, null, null);
+                            }
+                        }
+                    }
+                }
+                if (res == AppErrorDialog.FORCE_QUIT) {
+                    long orig = Binder.clearCallingIdentity();
+                    try {
+                        // Kill it with fire!
+                        mService.mStackSupervisor.handleAppCrashLocked(r);
+                        if (!r.persistent) {
+                            mService.removeProcessLocked(r, false, false, "crash");
+                            mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+                        }
+                    } finally {
+                        Binder.restoreCallingIdentity(orig);
+                    }
+                }
+                if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
+                    appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
+                }
+                if (r != null && !r.isolated && res != AppErrorDialog.RESTART) {
+                    // XXX Can't keep track of crash time for isolated processes,
+                    // since they don't have a persistent identity.
+                    mProcessCrashTimes.put(r.info.processName, r.uid,
+                            SystemClock.uptimeMillis());
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+
+        if (appErrorIntent != null) {
+            try {
+                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
+            } catch (ActivityNotFoundException e) {
+                Slog.w(TAG, "bug report receiver dissappeared", e);
+            }
+        }
+    }
+
+    private boolean makeAppCrashingLocked(ProcessRecord app,
+            String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
+        app.crashing = true;
+        app.crashingReport = generateProcessError(app,
+                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
+        startAppProblemLocked(app);
+        app.stopFreezingAllLocked();
+        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace,
+                data);
+    }
+
+    void startAppProblemLocked(ProcessRecord app) {
+        // If this app is not running under the current user, then we
+        // can't give it a report button because that would require
+        // launching the report UI under a different user.
+        app.errorReportReceiver = null;
+
+        for (int userId : mService.mUserController.getCurrentProfileIdsLocked()) {
+            if (app.userId == userId) {
+                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
+                        mContext, app.info.packageName, app.info.flags);
+            }
+        }
+        mService.skipCurrentReceiverLocked(app);
+    }
+
+    /**
+     * Generate a process error record, suitable for attachment to a ProcessRecord.
+     *
+     * @param app The ProcessRecord in which the error occurred.
+     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
+     *                      ActivityManager.AppErrorStateInfo
+     * @param activity The activity associated with the crash, if known.
+     * @param shortMsg Short message describing the crash.
+     * @param longMsg Long message describing the crash.
+     * @param stackTrace Full crash stack trace, may be null.
+     *
+     * @return Returns a fully-formed AppErrorStateInfo record.
+     */
+    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
+            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
+        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
+
+        report.condition = condition;
+        report.processName = app.processName;
+        report.pid = app.pid;
+        report.uid = app.info.uid;
+        report.tag = activity;
+        report.shortMsg = shortMsg;
+        report.longMsg = longMsg;
+        report.stackTrace = stackTrace;
+
+        return report;
+    }
+
+    Intent createAppErrorIntentLocked(ProcessRecord r,
+            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
+        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
+        if (report == null) {
+            return null;
+        }
+        Intent result = new Intent(Intent.ACTION_APP_ERROR);
+        result.setComponent(r.errorReportReceiver);
+        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
+        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return result;
+    }
+
+    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
+            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
+        if (r.errorReportReceiver == null) {
+            return null;
+        }
+
+        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
+            return null;
+        }
+
+        ApplicationErrorReport report = new ApplicationErrorReport();
+        report.packageName = r.info.packageName;
+        report.installerPackageName = r.errorReportReceiver.getPackageName();
+        report.processName = r.processName;
+        report.time = timeMillis;
+        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+
+        if (r.crashing || r.forceCrashReport) {
+            report.type = ApplicationErrorReport.TYPE_CRASH;
+            report.crashInfo = crashInfo;
+        } else if (r.notResponding) {
+            report.type = ApplicationErrorReport.TYPE_ANR;
+            report.anrInfo = new ApplicationErrorReport.AnrInfo();
+
+            report.anrInfo.activity = r.notRespondingReport.tag;
+            report.anrInfo.cause = r.notRespondingReport.shortMsg;
+            report.anrInfo.info = r.notRespondingReport.longMsg;
+        }
+
+        return report;
+    }
+
+    boolean handleAppCrashLocked(ProcessRecord app, String reason,
+            String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
+        long now = SystemClock.uptimeMillis();
+
+        Long crashTime;
+        Long crashTimePersistent;
+        if (!app.isolated) {
+            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
+            crashTimePersistent = mProcessCrashTimesPersistent.get(app.info.processName, app.uid);
+        } else {
+            crashTime = crashTimePersistent = null;
+        }
+        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
+            // This process loses!
+            Slog.w(TAG, "Process " + app.info.processName
+                    + " has crashed too many times: killing!");
+            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
+                    app.userId, app.info.processName, app.uid);
+            mService.mStackSupervisor.handleAppCrashLocked(app);
+            if (!app.persistent) {
+                // We don't want to start this process again until the user
+                // explicitly does so...  but for persistent process, we really
+                // need to keep it running.  If a persistent process is actually
+                // repeatedly crashing, then badness for everyone.
+                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
+                        app.info.processName);
+                if (!app.isolated) {
+                    // XXX We don't have a way to mark isolated processes
+                    // as bad, since they don't have a peristent identity.
+                    mBadProcesses.put(app.info.processName, app.uid,
+                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
+                    mProcessCrashTimes.remove(app.info.processName, app.uid);
+                }
+                app.bad = true;
+                app.removed = true;
+                // Don't let services in this process be restarted and potentially
+                // annoy the user repeatedly.  Unless it is persistent, since those
+                // processes run critical code.
+                mService.removeProcessLocked(app, false, false, "crash");
+                mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+                return false;
+            }
+            mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+        } else {
+            TaskRecord affectedTask =
+                    mService.mStackSupervisor.finishTopRunningActivityLocked(app, reason);
+            if (data != null) {
+                data.task = affectedTask;
+            }
+            if (data != null && crashTimePersistent != null
+                    && now < crashTimePersistent + ProcessList.MIN_CRASH_INTERVAL) {
+                data.repeating = true;
+            }
+        }
+
+        // Bump up the crash count of any services currently running in the proc.
+        for (int i=app.services.size()-1; i>=0; i--) {
+            // Any services running in the application need to be placed
+            // back in the pending list.
+            ServiceRecord sr = app.services.valueAt(i);
+            sr.crashCount++;
+        }
+
+        // If the crashing process is what we consider to be the "home process" and it has been
+        // replaced by a third-party app, clear the package preferred activities from packages
+        // with a home activity running in the process to prevent a repeatedly crashing app
+        // from blocking the user to manually clear the list.
+        final ArrayList<ActivityRecord> activities = app.activities;
+        if (app == mService.mHomeProcess && activities.size() > 0
+                && (mService.mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.isHomeActivity()) {
+                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
+                    try {
+                        ActivityThread.getPackageManager()
+                                .clearPackagePreferredActivities(r.packageName);
+                    } catch (RemoteException c) {
+                        // pm is in same process, this will never happen.
+                    }
+                }
+            }
+        }
+
+        if (!app.isolated) {
+            // XXX Can't keep track of crash times for isolated processes,
+            // because they don't have a perisistent identity.
+            mProcessCrashTimes.put(app.info.processName, app.uid, now);
+            mProcessCrashTimesPersistent.put(app.info.processName, app.uid, now);
+        }
+
+        if (app.crashHandler != null) mService.mHandler.post(app.crashHandler);
+        return true;
+    }
+
+    void handleShowAppErrorUi(Message msg) {
+        AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
+        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
+        synchronized (mService) {
+            ProcessRecord proc = data.proc;
+            AppErrorResult res = data.result;
+            if (proc != null && proc.crashDialog != null) {
+                Slog.e(TAG, "App already has crash dialog: " + proc);
+                if (res != null) {
+                    res.set(0);
+                }
+                return;
+            }
+            boolean isBackground = (UserHandle.getAppId(proc.uid)
+                    >= Process.FIRST_APPLICATION_UID
+                    && proc.pid != MY_PID);
+            for (int userId : mService.mUserController.getCurrentProfileIdsLocked()) {
+                isBackground &= (proc.userId != userId);
+            }
+            if (isBackground && !showBackground) {
+                Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
+                if (res != null) {
+                    res.set(0);
+                }
+                return;
+            }
+            final boolean crashSilenced = mAppsNotReportingCrashes != null &&
+                    mAppsNotReportingCrashes.contains(proc.info.packageName);
+            if (mService.canShowErrorDialogs() && !crashSilenced) {
+                Dialog d = new AppErrorDialog(mContext, mService, data);
+                d.show();
+                proc.crashDialog = d;
+            } else {
+                // The device is asleep, so just pretend that the user
+                // saw a crash dialog and hit "force quit".
+                if (res != null) {
+                    res.set(0);
+                }
+            }
+        }
+    }
+
+    void stopReportingCrashesLocked(ProcessRecord proc) {
+        if (mAppsNotReportingCrashes == null) {
+            mAppsNotReportingCrashes = new ArraySet<>();
+        }
+        mAppsNotReportingCrashes.add(proc.info.packageName);
+    }
+
+    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
+            ActivityRecord parent, boolean aboveSystem, final String annotation) {
+        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
+        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
+
+        if (mService.mController != null) {
+            try {
+                // 0 == continue, -1 = kill process immediately
+                int res = mService.mController.appEarlyNotResponding(app.processName, app.pid, annotation);
+                if (res < 0 && app.pid != MY_PID) {
+                    app.kill("anr", true);
+                }
+            } catch (RemoteException e) {
+                mService.mController = null;
+                Watchdog.getInstance().setActivityController(null);
+            }
+        }
+
+        long anrTime = SystemClock.uptimeMillis();
+        if (ActivityManagerService.MONITOR_CPU_USAGE) {
+            mService.updateCpuStatsNow();
+        }
+
+        synchronized (mService) {
+            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
+            if (mService.mShuttingDown) {
+                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
+                return;
+            } else if (app.notResponding) {
+                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
+                return;
+            } else if (app.crashing) {
+                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
+                return;
+            }
+
+            // In case we come through here for the same app before completing
+            // this one, mark as anring now so we will bail out.
+            app.notResponding = true;
+
+            // Log the ANR to the event log.
+            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
+                    app.processName, app.info.flags, annotation);
+
+            // Dump thread traces as quickly as we can, starting with "interesting" processes.
+            firstPids.add(app.pid);
+
+            int parentPid = app.pid;
+            if (parent != null && parent.app != null && parent.app.pid > 0) {
+                parentPid = parent.app.pid;
+            }
+            if (parentPid != app.pid) firstPids.add(parentPid);
+
+            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
+
+            for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) {
+                ProcessRecord r = mService.mLruProcesses.get(i);
+                if (r != null && r.thread != null) {
+                    int pid = r.pid;
+                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
+                        if (r.persistent) {
+                            firstPids.add(pid);
+                        } else {
+                            lastPids.put(pid, Boolean.TRUE);
+                        }
+                    }
+                }
+            }
+        }
+
+        // Log the ANR to the main log.
+        StringBuilder info = new StringBuilder();
+        info.setLength(0);
+        info.append("ANR in ").append(app.processName);
+        if (activity != null && activity.shortComponentName != null) {
+            info.append(" (").append(activity.shortComponentName).append(")");
+        }
+        info.append("\n");
+        info.append("PID: ").append(app.pid).append("\n");
+        if (annotation != null) {
+            info.append("Reason: ").append(annotation).append("\n");
+        }
+        if (parent != null && parent != activity) {
+            info.append("Parent: ").append(parent.shortComponentName).append("\n");
+        }
+
+        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
+
+        File tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
+                NATIVE_STACKS_OF_INTEREST);
+
+        String cpuInfo = null;
+        if (ActivityManagerService.MONITOR_CPU_USAGE) {
+            mService.updateCpuStatsNow();
+            synchronized (mService.mProcessCpuTracker) {
+                cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime);
+            }
+            info.append(processCpuTracker.printCurrentLoad());
+            info.append(cpuInfo);
+        }
+
+        info.append(processCpuTracker.printCurrentState(anrTime));
+
+        Slog.e(TAG, info.toString());
+        if (tracesFile == null) {
+            // There is no trace file, so dump (only) the alleged culprit's threads to the log
+            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
+        }
+
+        mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
+                cpuInfo, tracesFile, null);
+
+        if (mService.mController != null) {
+            try {
+                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
+                int res = mService.mController.appNotResponding(
+                        app.processName, app.pid, info.toString());
+                if (res != 0) {
+                    if (res < 0 && app.pid != MY_PID) {
+                        app.kill("anr", true);
+                    } else {
+                        synchronized (mService) {
+                            mService.mServices.scheduleServiceTimeoutLocked(app);
+                        }
+                    }
+                    return;
+                }
+            } catch (RemoteException e) {
+                mService.mController = null;
+                Watchdog.getInstance().setActivityController(null);
+            }
+        }
+
+        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
+        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
+
+        synchronized (mService) {
+            mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
+
+            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
+                app.kill("bg anr", true);
+                return;
+            }
+
+            // Set the app's notResponding state, and look up the errorReportReceiver
+            makeAppNotRespondingLocked(app,
+                    activity != null ? activity.shortComponentName : null,
+                    annotation != null ? "ANR " + annotation : "ANR",
+                    info.toString());
+
+            // Bring up the infamous App Not Responding dialog
+            Message msg = Message.obtain();
+            HashMap<String, Object> map = new HashMap<String, Object>();
+            msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
+            msg.obj = map;
+            msg.arg1 = aboveSystem ? 1 : 0;
+            map.put("app", app);
+            if (activity != null) {
+                map.put("activity", activity);
+            }
+
+            mService.mUiHandler.sendMessage(msg);
+        }
+    }
+
+    private void makeAppNotRespondingLocked(ProcessRecord app,
+            String activity, String shortMsg, String longMsg) {
+        app.notResponding = true;
+        app.notRespondingReport = generateProcessError(app,
+                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
+                activity, shortMsg, longMsg, null);
+        startAppProblemLocked(app);
+        app.stopFreezingAllLocked();
+    }
+
+    void handleShowAnrUi(Message msg) {
+        synchronized (mService) {
+            HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
+            ProcessRecord proc = (ProcessRecord)data.get("app");
+            if (proc != null && proc.anrDialog != null) {
+                Slog.e(TAG, "App already has anr dialog: " + proc);
+                return;
+            }
+
+            Intent intent = new Intent("android.intent.action.ANR");
+            if (!mService.mProcessesReady) {
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                        | Intent.FLAG_RECEIVER_FOREGROUND);
+            }
+            mService.broadcastIntentLocked(null, null, intent,
+                    null, null, 0, null, null, null, AppOpsManager.OP_NONE,
+                    null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
+
+            if (mService.canShowErrorDialogs()) {
+                Dialog d = new AppNotRespondingDialog(mService,
+                        mContext, proc, (ActivityRecord)data.get("activity"),
+                        msg.arg1 != 0);
+                d.show();
+                proc.anrDialog = d;
+            } else {
+                // Just kill the app if there is no dialog to be shown.
+                mService.killAppAtUsersRequest(proc, null);
+            }
+        }
+    }
+
+    /**
+     * Information about a process that is currently marked as bad.
+     */
+    static final class BadProcessInfo {
+        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
+            this.time = time;
+            this.shortMsg = shortMsg;
+            this.longMsg = longMsg;
+            this.stack = stack;
+        }
+
+        final long time;
+        final String shortMsg;
+        final String longMsg;
+        final String stack;
+    }
+
+}
diff --git a/services/core/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
index f4c1664..4587b72 100644
--- a/services/core/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
@@ -117,7 +117,7 @@
                         ProcessRecord app = mProc;
 
                         if (msg.what == WAIT_AND_REPORT) {
-                            appErrorIntent = mService.createAppErrorIntentLocked(app,
+                            appErrorIntent = mService.mAppErrors.createAppErrorIntentLocked(app,
                                     System.currentTimeMillis(), null);
                         }
 
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 82862e8..0f7dff2 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -855,6 +855,18 @@
         }
     }
 
+    @Override
+    public void noteBleScanStarted(WorkSource ws) {
+        enforceCallingPermission();
+        Slog.d(TAG, "BLE scan started for " + ws);
+    }
+
+    @Override
+    public void noteBleScanStopped(WorkSource ws) {
+        enforceCallingPermission();
+        Slog.d(TAG, "BLE scan stopped for " + ws);
+    }
+
     public boolean isOnBattery() {
         return mStats.isOnBattery();
     }
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 622aa16..37b0af1 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -199,7 +199,7 @@
 
         @Override
         public void run() {
-            mService.appNotResponding(mApp, null, null, false, mAnnotation);
+            mService.mAppErrors.appNotResponding(mApp, null, null, false, mAnnotation);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 05702af..9c139d5 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -24,6 +24,8 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
 
+import com.google.android.collect.Sets;
+
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.content.ComponentName;
@@ -45,6 +47,7 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.Set;
 
 /**
  * Class for managing the recent tasks list.
@@ -188,6 +191,21 @@
         }
     }
 
+    void onPackagesSuspendedChanged(String[] packages, boolean suspended, int userId) {
+        final Set<String> packageNames = Sets.newHashSet(packages);
+        for (int i = size() - 1; i >= 0; --i) {
+            final TaskRecord tr = get(i);
+            if (tr.realActivity != null
+                    && packageNames.contains(tr.realActivity.getPackageName())
+                    && tr.userId == userId
+                    && tr.realActivitySuspended != suspended) {
+               tr.realActivitySuspended = suspended;
+               notifyTaskPersisterLocked(tr, false);
+            }
+        }
+
+    }
+
     /**
      * Update the recent tasks lists: make sure tasks should still be here (their
      * applications / activities still exist), update their availability, fix-up ordering
@@ -405,6 +423,8 @@
 
         int recentsCount = size();
         // Quick case: never add voice sessions.
+        // TODO: VI what about if it's just an activity?
+        // Probably nothing to do here
         if (task.voiceSession != null) {
             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
                     "addRecent: not adding voice interaction " + task);
@@ -681,5 +701,4 @@
         // Let the caller know where we left off.
         return start + tmpSize;
     }
-
 }
diff --git a/services/core/java/com/android/server/am/StrictModeViolationDialog.java b/services/core/java/com/android/server/am/StrictModeViolationDialog.java
index fda1ec1..6da84bd 100644
--- a/services/core/java/com/android/server/am/StrictModeViolationDialog.java
+++ b/services/core/java/com/android/server/am/StrictModeViolationDialog.java
@@ -73,7 +73,6 @@
                       mHandler.obtainMessage(ACTION_OK_AND_REPORT));
         }
 
-        setTitle(res.getText(com.android.internal.R.string.aerr_title));
         getWindow().addPrivateFlags(PRIVATE_FLAG_SYSTEM_ERROR);
         getWindow().setTitle("Strict Mode Violation: " + app.info.processName);
 
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 4ce8b2f..fd787df 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -95,6 +95,7 @@
     private static final String TAG_INTENT = "intent";
     private static final String TAG_AFFINITYINTENT = "affinity_intent";
     static final String ATTR_REALACTIVITY = "real_activity";
+    static final String ATTR_REALACTIVITY_SUSPENDED = "real_activity_suspended";
     private static final String ATTR_ORIGACTIVITY = "orig_activity";
     private static final String TAG_ACTIVITY = "activity";
     private static final String ATTR_AFFINITY = "affinity";
@@ -136,6 +137,8 @@
     int effectiveUid;       // The current effective uid of the identity of this task.
     ComponentName origActivity; // The non-alias activity component of the intent.
     ComponentName realActivity; // The actual activity component that started the task.
+    boolean realActivitySuspended; // True if the actual activity component that started the
+                                   // task is suspended.
     long firstActiveTime;   // First time this task was active.
     long lastActiveTime;    // Last time this task was active, including sleep.
     boolean inRecents;      // Actually in the recents list?
@@ -305,7 +308,7 @@
             boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
             TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId,
             int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
-            boolean resizeable, boolean privileged) {
+            boolean resizeable, boolean privileged, boolean realActivitySuspended) {
         mService = service;
         mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
                 TaskPersister.IMAGE_EXTENSION;
@@ -319,6 +322,7 @@
         voiceSession = null;
         voiceInteractor = null;
         realActivity = _realActivity;
+        realActivitySuspended = realActivitySuspended;
         origActivity = _origActivity;
         rootWasReset = _rootWasReset;
         isAvailable = true;
@@ -1027,6 +1031,7 @@
         if (realActivity != null) {
             out.attribute(null, ATTR_REALACTIVITY, realActivity.flattenToShortString());
         }
+        out.attribute(null, ATTR_REALACTIVITY_SUSPENDED, String.valueOf(realActivitySuspended));
         if (origActivity != null) {
             out.attribute(null, ATTR_ORIGACTIVITY, origActivity.flattenToShortString());
         }
@@ -1105,6 +1110,7 @@
         Intent affinityIntent = null;
         ArrayList<ActivityRecord> activities = new ArrayList<>();
         ComponentName realActivity = null;
+        boolean realActivitySuspended = false;
         ComponentName origActivity = null;
         String affinity = null;
         String rootAffinity = null;
@@ -1143,6 +1149,8 @@
                 if (taskId == INVALID_TASK_ID) taskId = Integer.valueOf(attrValue);
             } else if (ATTR_REALACTIVITY.equals(attrName)) {
                 realActivity = ComponentName.unflattenFromString(attrValue);
+            } else if (ATTR_REALACTIVITY_SUSPENDED.equals(attrName)) {
+                realActivitySuspended = Boolean.valueOf(attrValue);
             } else if (ATTR_ORIGACTIVITY.equals(attrName)) {
                 origActivity = ComponentName.unflattenFromString(attrValue);
             } else if (ATTR_AFFINITY.equals(attrName)) {
@@ -1253,7 +1261,8 @@
                 autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
                 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
                 taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId,
-                taskAffiliationColor, callingUid, callingPackage, resizeable, privileged);
+                taskAffiliationColor, callingUid, callingPackage, resizeable, privileged,
+                realActivitySuspended);
         task.updateOverrideConfiguration(bounds);
 
         for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 8c16872..a21570ce 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -525,7 +525,7 @@
         List<UserInfo> profilesToStart = new ArrayList<>(profiles.size());
         for (UserInfo user : profiles) {
             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
-                    && user.id != mCurrentUserId) {
+                    && user.id != mCurrentUserId && !user.isQuietModeEnabled()) {
                 profilesToStart.add(user);
             }
         }
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 3b43633..a73a67a 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -19,6 +19,10 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothPan;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothProfile.ServiceListener;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -38,20 +42,25 @@
 import android.net.NetworkRequest;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
+import android.net.wifi.WifiManager;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Parcel;
+import android.os.ResultReceiver;
+import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
 import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.IState;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import com.android.server.IoThread;
@@ -59,8 +68,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.net.InetAddress;
 import java.net.Inet4Address;
+import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -109,6 +118,10 @@
 
     private BroadcastReceiver mStateReceiver;
 
+    // {@link ComponentName} of the Service used to run tether provisioning.
+    private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(Resources
+            .getSystem().getString(com.android.internal.R.string.config_wifi_tether_enable));
+
     private static final String USB_NEAR_IFACE_ADDR      = "192.168.42.129";
     private static final int USB_PREFIX_LENGTH        = 24;
 
@@ -140,11 +153,10 @@
                                          // when RNDIS is enabled
 
     public Tethering(Context context, INetworkManagementService nmService,
-            INetworkStatsService statsService, Looper looper) {
+            INetworkStatsService statsService) {
         mContext = context;
         mNMService = nmService;
         mStatsService = statsService;
-        mLooper = looper;
 
         mPublicSync = new Object();
 
@@ -332,6 +344,218 @@
         }
     }
 
+    public void startTethering(int type, ResultReceiver receiver,
+            boolean showProvisioningUi) {
+        if (!isTetherProvisioningRequired()) {
+            enableTetheringInternal(type, true, receiver);
+            return;
+        }
+
+        if (showProvisioningUi) {
+            runUiTetherProvisioningAndEnable(type, receiver);
+        } else {
+            runSilentTetherProvisioningAndEnable(type, receiver);
+        }
+    }
+
+    public void stopTethering(int type) {
+        enableTetheringInternal(type, false, null);
+        if (isTetherProvisioningRequired()) {
+            cancelTetherProvisioningRechecks(type);
+        }
+    }
+
+    /**
+     * Check if the device requires a provisioning check in order to enable tethering.
+     *
+     * @return a boolean - {@code true} indicating tether provisioning is required by the carrier.
+     */
+    private boolean isTetherProvisioningRequired() {
+        String[] provisionApp = mContext.getResources().getStringArray(
+                com.android.internal.R.array.config_mobile_hotspot_provision_app);
+        if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)
+                || provisionApp == null) {
+            return false;
+        }
+
+        // Check carrier config for entitlement checks
+        final CarrierConfigManager configManager = (CarrierConfigManager) mContext
+             .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        boolean isEntitlementCheckRequired = configManager.getConfig().getBoolean(
+             CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
+
+        if (!isEntitlementCheckRequired) {
+            return false;
+        }
+        return (provisionApp.length == 2);
+    }
+
+    /**
+     * Enables or disables tethering for the given type. This should only be called once
+     * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks
+     * for the specified interface.
+     */
+    private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {
+        boolean isProvisioningRequired = isTetherProvisioningRequired();
+        switch (type) {
+            case ConnectivityManager.TETHERING_WIFI:
+                final WifiManager wifiManager =
+                        (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+                if (wifiManager.setWifiApEnabled(null, enable)) {
+                    sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_NO_ERROR);
+                    if (enable && isProvisioningRequired) {
+                        scheduleProvisioningRechecks(type);
+                    }
+                } else{
+                    sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_MASTER_ERROR);
+                }
+                break;
+            case ConnectivityManager.TETHERING_USB:
+                int result = setUsbTethering(enable);
+                if (enable && isProvisioningRequired &&
+                        result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                    scheduleProvisioningRechecks(type);
+                }
+                sendTetherResult(receiver, result);
+                break;
+            case ConnectivityManager.TETHERING_BLUETOOTH:
+                setBluetoothTethering(enable, receiver);
+                break;
+            default:
+                Log.w(TAG, "Invalid tether type.");
+                sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE);
+        }
+    }
+
+    private void sendTetherResult(ResultReceiver receiver, int result) {
+        if (receiver != null) {
+            receiver.send(result, null);
+        }
+    }
+
+    private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) {
+        final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        if (adapter == null || !adapter.isEnabled()) {
+            Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: " +
+                    (adapter == null));
+            sendTetherResult(receiver, ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL);
+            return;
+        }
+
+        adapter.getProfileProxy(mContext, new ServiceListener() {
+            @Override
+            public void onServiceDisconnected(int profile) { }
+
+            @Override
+            public void onServiceConnected(int profile, BluetoothProfile proxy) {
+                ((BluetoothPan) proxy).setBluetoothTethering(enable);
+                // TODO: Enabling bluetooth tethering can fail asynchronously here.
+                // We should figure out a way to bubble up that failure instead of sending success.
+                int result = ((BluetoothPan) proxy).isTetheringOn() ?
+                        ConnectivityManager.TETHER_ERROR_NO_ERROR :
+                        ConnectivityManager.TETHER_ERROR_MASTER_ERROR;
+                sendTetherResult(receiver, result);
+                if (enable && isTetherProvisioningRequired()) {
+                    scheduleProvisioningRechecks(ConnectivityManager.TETHERING_BLUETOOTH);
+                }
+                adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
+            }
+        }, BluetoothProfile.PAN);
+    }
+
+    private void runUiTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
+        ResultReceiver proxyReceiver = getProxyReceiver(type, receiver);
+        sendUiTetherProvisionIntent(type, proxyReceiver);
+    }
+
+    private void sendUiTetherProvisionIntent(int type, ResultReceiver receiver) {
+        Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING);
+        intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type);
+        intent.putExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK, receiver);
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    /**
+     * Creates a proxy {@link ResultReceiver} which enables tethering if the provsioning result is
+     * successful before firing back up to the wrapped receiver.
+     *
+     * @param type The type of tethering being enabled.
+     * @param receiver A ResultReceiver which will be called back with an int resultCode.
+     * @return The proxy receiver.
+     */
+    private ResultReceiver getProxyReceiver(final int type, final ResultReceiver receiver) {
+        ResultReceiver rr = new ResultReceiver(null) {
+            @Override
+            protected void onReceiveResult(int resultCode, Bundle resultData) {
+                // If provisioning is successful, enable tethering, otherwise just send the error.
+                if (resultCode == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                    enableTetheringInternal(type, true, receiver);
+                } else {
+                    sendTetherResult(receiver, resultCode);
+                }
+            }
+        };
+
+        // The following is necessary to avoid unmarshalling issues when sending the receiver
+        // across proccesses.
+        Parcel parcel = Parcel.obtain();
+        rr.writeToParcel(parcel,0);
+        parcel.setDataPosition(0);
+        ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+        return receiverForSending;
+    }
+
+    private void scheduleProvisioningRechecks(int type) {
+        Intent intent = new Intent();
+        intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type);
+        intent.putExtra(ConnectivityManager.EXTRA_SET_ALARM, true);
+        intent.setComponent(TETHER_SERVICE);
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mContext.startServiceAsUser(intent, UserHandle.CURRENT);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
+        ResultReceiver proxyReceiver = getProxyReceiver(type, receiver);
+        sendSilentTetherProvisionIntent(type, proxyReceiver);
+    }
+
+    private void sendSilentTetherProvisionIntent(int type, ResultReceiver receiver) {
+        Intent intent = new Intent();
+        intent.putExtra(ConnectivityManager.EXTRA_ADD_TETHER_TYPE, type);
+        intent.putExtra(ConnectivityManager.EXTRA_RUN_PROVISION, true);
+        intent.putExtra(ConnectivityManager.EXTRA_PROVISION_CALLBACK, receiver);
+        intent.setComponent(TETHER_SERVICE);
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mContext.startServiceAsUser(intent, UserHandle.CURRENT);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void cancelTetherProvisioningRechecks(int type) {
+        if (getConnectivityManager().isTetheringSupported()) {
+            Intent intent = new Intent();
+            intent.putExtra(ConnectivityManager.EXTRA_REM_TETHER_TYPE, type);
+            intent.setComponent(TETHER_SERVICE);
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                mContext.startServiceAsUser(intent, UserHandle.CURRENT);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
     public int tether(String iface) {
         if (DBG) Log.d(TAG, "Tethering " + iface);
         TetherInterfaceSM sm = null;
@@ -615,13 +839,23 @@
         synchronized (mPublicSync) {
             if (enable) {
                 if (mRndisEnabled) {
-                    tetherUsb(true);
+                    final long ident = Binder.clearCallingIdentity();
+                    try {
+                        tetherUsb(true);
+                    } finally {
+                        Binder.restoreCallingIdentity(ident);
+                    }
                 } else {
                     mUsbTetherRequested = true;
                     usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS);
                 }
             } else {
-                tetherUsb(false);
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    tetherUsb(false);
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
                 if (mRndisEnabled) {
                     usbManager.setCurrentFunction(null);
                 }
@@ -1407,15 +1641,6 @@
         private final AtomicInteger mSimBcastGenerationNumber = new AtomicInteger(0);
         private SimChangeBroadcastReceiver mBroadcastReceiver = null;
 
-        // keep consts in sync with packages/apps/Settings TetherSettings.java
-        private static final int WIFI_TETHERING      = 0;
-        private static final int USB_TETHERING       = 1;
-        private static final int BLUETOOTH_TETHERING = 2;
-
-        // keep consts in sync with packages/apps/Settings TetherService.java
-        private static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
-        private static final String EXTRA_RUN_PROVISION = "extraRunProvision";
-
         private void startListeningForSimChanges() {
             if (DBG) Log.d(TAG, "startListeningForSimChanges");
             if (mBroadcastReceiver == null) {
@@ -1472,8 +1697,6 @@
                     try {
                         if (mContext.getResources().getString(com.android.internal.R.string.
                                 config_mobile_hotspot_provision_app_no_ui).isEmpty() == false) {
-                            final String tetherService = mContext.getResources().getString(
-                                    com.android.internal.R.string.config_wifi_tether_enable);
                             ArrayList<Integer> tethered = new ArrayList<Integer>();
                             synchronized (mPublicSync) {
                                 Set ifaces = mIfaces.keySet();
@@ -1481,21 +1704,25 @@
                                     TetherInterfaceSM sm = mIfaces.get(iface);
                                     if (sm != null && sm.isTethered()) {
                                         if (isUsb((String)iface)) {
-                                            tethered.add(new Integer(USB_TETHERING));
+                                            tethered.add(new Integer(
+                                                    ConnectivityManager.TETHERING_USB));
                                         } else if (isWifi((String)iface)) {
-                                            tethered.add(new Integer(WIFI_TETHERING));
+                                            tethered.add(new Integer(
+                                                    ConnectivityManager.TETHERING_WIFI));
                                         } else if (isBluetooth((String)iface)) {
-                                            tethered.add(new Integer(BLUETOOTH_TETHERING));
+                                            tethered.add(new Integer(
+                                                    ConnectivityManager.TETHERING_BLUETOOTH));
                                         }
                                     }
                                 }
                             }
                             for (int tetherType : tethered) {
                                 Intent startProvIntent = new Intent();
-                                startProvIntent.putExtra(EXTRA_ADD_TETHER_TYPE, tetherType);
-                                startProvIntent.putExtra(EXTRA_RUN_PROVISION, true);
-                                startProvIntent.setComponent(
-                                        ComponentName.unflattenFromString(tetherService));
+                                startProvIntent.putExtra(
+                                        ConnectivityManager.EXTRA_ADD_TETHER_TYPE, tetherType);
+                                startProvIntent.putExtra(
+                                        ConnectivityManager.EXTRA_RUN_PROVISION, true);
+                                startProvIntent.setComponent(TETHER_SERVICE);
                                 mContext.startServiceAsUser(startProvIntent, UserHandle.CURRENT);
                             }
                             Log.d(TAG, "re-evaluate provisioning");
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index 206cc8a..a633996 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -17,6 +17,7 @@
 package com.android.server.dreams;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -131,7 +132,7 @@
 
             mDreamStartTime = SystemClock.elapsedRealtime();
             MetricsLogger.visible(mContext,
-                    mCurrentDream.mCanDoze ? MetricsLogger.DOZING : MetricsLogger.DREAMING);
+                    mCurrentDream.mCanDoze ? MetricsEvent.DOZING : MetricsEvent.DREAMING);
 
             try {
                 mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM);
@@ -196,7 +197,7 @@
                     + ", isTest=" + oldDream.mIsTest + ", canDoze=" + oldDream.mCanDoze
                     + ", userId=" + oldDream.mUserId);
             MetricsLogger.hidden(mContext,
-                    oldDream.mCanDoze ? MetricsLogger.DOZING : MetricsLogger.DREAMING);
+                    oldDream.mCanDoze ? MetricsEvent.DOZING : MetricsEvent.DREAMING);
             MetricsLogger.histogram(mContext,
                     oldDream.mCanDoze ? "dozing_minutes" : "dreaming_minutes" ,
                     (int) ((SystemClock.elapsedRealtime() - mDreamStartTime) / (1000L * 60L)));
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 7ac3c4b..13e7648 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -19,6 +19,7 @@
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.trust.TrustManager;
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AppOpsManager;
@@ -47,6 +48,7 @@
 import android.util.Slog;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.server.SystemService;
 
 import org.json.JSONArray;
@@ -103,6 +105,7 @@
     private static final int MAX_FAILED_ATTEMPTS = 5;
     private static final int FINGERPRINT_ACQUIRED_GOOD = 0;
     private final String mKeyguardPackage;
+    private int mCurrentUserId = UserHandle.USER_CURRENT;
 
     Handler mHandler = new Handler() {
         @Override
@@ -125,6 +128,7 @@
     private IFingerprintDaemon mDaemon;
     private final PowerManager mPowerManager;
     private final AlarmManager mAlarmManager;
+    private final UserManager mUserManager;
 
     private final BroadcastReceiver mLockoutReceiver = new BroadcastReceiver() {
         @Override
@@ -152,6 +156,7 @@
         mAlarmManager = mContext.getSystemService(AlarmManager.class);
         mContext.registerReceiver(mLockoutReceiver, new IntentFilter(ACTION_LOCKOUT_RESET),
                 RESET_FINGERPRINT_LOCKOUT, null /* handler */);
+        mUserManager = UserManager.get(mContext);
     }
 
     @Override
@@ -170,7 +175,7 @@
                     mDaemon.init(mDaemonCallback);
                     mHalDeviceId = mDaemon.openHal();
                     if (mHalDeviceId != 0) {
-                        updateActiveGroup(ActivityManager.getCurrentUser());
+                        updateActiveGroup(ActivityManager.getCurrentUser(), null);
                     } else {
                         Slog.w(TAG, "Failed to open Fingerprint HAL!");
                         mDaemon = null;
@@ -261,7 +266,7 @@
     }
 
     void handleUserSwitching(int userId) {
-        updateActiveGroup(userId);
+        updateActiveGroup(userId, null);
     }
 
     private void removeClient(ClientMonitor client) {
@@ -414,7 +419,7 @@
         removeClient(mEnrollClient);
     }
 
-    void startAuthentication(IBinder token, long opId, int groupId,
+    void startAuthentication(IBinder token, long opId, int realUserId, int groupId,
             IFingerprintServiceReceiver receiver, int flags, boolean restricted,
             String opPackageName) {
         IFingerprintDaemon daemon = getFingerprintDaemon();
@@ -423,6 +428,7 @@
             return;
         }
         stopPendingOperations(true);
+        updateActiveGroup(groupId, opPackageName);
         mAuthClient = new ClientMonitor(token, receiver, groupId, restricted, opPackageName);
         if (inLockoutMode()) {
             Slog.v(TAG, "In lockout mode; disallowing authentication");
@@ -564,7 +570,7 @@
         checkPermission(USE_FINGERPRINT);
         final int uid = Binder.getCallingUid();
         final int pid = Binder.getCallingPid();
-        if (opPackageName.equals(mKeyguardPackage)) {
+        if (isKeyguard(opPackageName)) {
             return true; // Keyguard is always allowed
         }
         if (!isCurrentUserOrProfile(UserHandle.getCallingUserId())) {
@@ -583,6 +589,14 @@
         return true;
     }
 
+    /**
+     * @param clientPackage
+     * @return true if this is keyguard package
+     */
+    private boolean isKeyguard(String clientPackage) {
+        return mKeyguardPackage.equals(clientPackage);
+    }
+
     private void addLockoutResetMonitor(FingerprintServiceLockoutResetMonitor monitor) {
         if (!mLockoutMonitors.contains(monitor)) {
             mLockoutMonitors.add(monitor);
@@ -673,7 +687,7 @@
         private boolean sendEnrollResult(int fpId, int groupId, int remaining) {
             if (receiver == null) return true; // client not listening
             FingerprintUtils.vibrateFingerprintSuccess(getContext());
-            MetricsLogger.action(mContext, MetricsLogger.ACTION_FINGERPRINT_ENROLL);
+            MetricsLogger.action(mContext, MetricsEvent.ACTION_FINGERPRINT_ENROLL);
             try {
                 receiver.onEnrollResult(mHalDeviceId, fpId, groupId, remaining);
                 return remaining == 0;
@@ -691,7 +705,7 @@
             boolean authenticated = fpId != 0;
             if (receiver != null) {
                 try {
-                    MetricsLogger.action(mContext, MetricsLogger.ACTION_FINGERPRINT_AUTH,
+                    MetricsLogger.action(mContext, MetricsEvent.ACTION_FINGERPRINT_AUTH,
                             authenticated);
                     if (!authenticated) {
                         receiver.onAuthenticationFailed(mHalDeviceId);
@@ -927,14 +941,15 @@
             // Group ID is arbitrarily set to parent profile user ID. It just represents
             // the default fingerprints for the user.
             final int effectiveGroupId = getEffectiveUserId(groupId);
+            final int realUserId = Binder.getCallingUid();
 
             final boolean restricted = isRestricted();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
                     MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0);
-                    startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted,
-                            opPackageName);
+                    startAuthentication(token, opId, realUserId, effectiveGroupId, receiver,
+                            flags, restricted, opPackageName);
                 }
             });
         }
@@ -953,6 +968,17 @@
         }
 
         @Override // Binder call
+        public void setActiveUser(final int userId) {
+            checkPermission(MANAGE_FINGERPRINT);
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    updateActiveGroup(userId, null);
+                }
+            });
+        }
+
+        @Override // Binder call
         public void remove(final IBinder token, final int fingerId, final int groupId,
                 final IFingerprintServiceReceiver receiver) {
             checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission
@@ -1102,33 +1128,56 @@
         listenForUserSwitches();
     }
 
-    private void updateActiveGroup(int userId) {
+    private void updateActiveGroup(int userId, String clientPackage) {
         IFingerprintDaemon daemon = getFingerprintDaemon();
         if (daemon != null) {
             try {
-                userId = getEffectiveUserId(userId);
-                final File systemDir = Environment.getUserSystemDirectory(userId);
-                final File fpDir = new File(systemDir, FP_DATA_DIR);
-                if (!fpDir.exists()) {
-                    if (!fpDir.mkdir()) {
-                        Slog.v(TAG, "Cannot make directory: " + fpDir.getAbsolutePath());
-                        return;
+                userId = getUserOrWorkProfileId(clientPackage, userId);
+                if (userId != mCurrentUserId) {
+                    final File systemDir = Environment.getUserSystemDirectory(userId);
+                    final File fpDir = new File(systemDir, FP_DATA_DIR);
+                    if (!fpDir.exists()) {
+                        if (!fpDir.mkdir()) {
+                            Slog.v(TAG, "Cannot make directory: " + fpDir.getAbsolutePath());
+                            return;
+                        }
+                        // Calling mkdir() from this process will create a directory with our
+                        // permissions (inherited from the containing dir). This command fixes
+                        // the label.
+                        if (!SELinux.restorecon(fpDir)) {
+                            Slog.w(TAG, "Restorecons failed. Directory will have wrong label.");
+                            return;
+                        }
                     }
-                    // Calling mkdir() from this process will create a directory with our
-                    // permissions (inherited from the containing dir). This command fixes
-                    // the label.
-                    if (!SELinux.restorecon(fpDir)) {
-                        Slog.w(TAG, "Restorecons failed. Directory will have wrong label.");
-                        return;
-                    }
+                    daemon.setActiveGroup(userId, fpDir.getAbsolutePath().getBytes());
+                    mCurrentUserId = userId;
                 }
-                daemon.setActiveGroup(userId, fpDir.getAbsolutePath().getBytes());
             } catch (RemoteException e) {
                 Slog.e(TAG, "Failed to setActiveGroup():", e);
             }
         }
     }
 
+    /**
+     * @param clientPackage the package of the caller
+     * @return the profile id
+     */
+    private int getUserOrWorkProfileId(String clientPackage, int userId) {
+        if (!isKeyguard(clientPackage) && isWorkProfile(userId)) {
+            return userId;
+        }
+        return getEffectiveUserId(userId);
+    }
+
+    /**
+     * @param userId
+     * @return true if this is a work profile
+     */
+    private boolean isWorkProfile(int userId) {
+        UserInfo info = mUserManager.getUserInfo(userId);
+        return info != null && info.isManagedProfile();
+    }
+
     private void listenForUserSwitches() {
         try {
             ActivityManagerNative.getDefault().registerUserSwitchObserver(
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index c63ce73..43cd44f 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -60,6 +60,7 @@
 import com.android.server.job.controllers.AppIdleController;
 import com.android.server.job.controllers.BatteryController;
 import com.android.server.job.controllers.ConnectivityController;
+import com.android.server.job.controllers.ContentObserverController;
 import com.android.server.job.controllers.IdleController;
 import com.android.server.job.controllers.JobStatus;
 import com.android.server.job.controllers.StateController;
@@ -109,6 +110,11 @@
      */
     static final int MIN_CONNECTIVITY_COUNT = 1;  // Run connectivity jobs as soon as ready.
     /**
+     * Minimum # of content trigger jobs that must be ready in order to force the JMS to schedule
+     * things early.
+     */
+    static final int MIN_CONTENT_COUNT = 1;
+    /**
      * Minimum # of jobs (with no particular constraints) for which the JMS will be happy running
      * some work early.
      * This is correlated with the amount of batching we'll be able to do.
@@ -229,7 +235,6 @@
         if (packageName != null) {
             jobStatus.setSource(packageName, userId);
         }
-        cancelJob(uId, job.getId());
         try {
             if (ActivityManagerNative.getDefault().getAppStartMode(uId,
                     job.getService().getPackageName()) == ActivityManager.APP_START_MODE_DISABLED) {
@@ -239,7 +244,15 @@
             }
         } catch (RemoteException e) {
         }
-        startTrackingJob(jobStatus);
+        if (DEBUG) Slog.d(TAG, "SCHEDULE: " + jobStatus.toShortString());
+        JobStatus toCancel;
+        synchronized (mJobs) {
+            toCancel = mJobs.getJobByUidAndJobId(uId, job.getId());
+        }
+        startTrackingJob(jobStatus, toCancel);
+        if (toCancel != null) {
+            cancelJobImpl(toCancel);
+        }
         mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
         return JobScheduler.RESULT_SUCCESS;
     }
@@ -316,9 +329,7 @@
     }
 
     private void cancelJobImpl(JobStatus cancelled) {
-        if (DEBUG) {
-            Slog.d(TAG, "Cancelling: " + cancelled);
-        }
+        if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
         stopTrackingJob(cancelled);
         synchronized (mJobs) {
             // Remove from pending queue.
@@ -410,6 +421,7 @@
         mControllers.add(IdleController.get(this));
         mControllers.add(BatteryController.get(this));
         mControllers.add(AppIdleController.get(this));
+        mControllers.add(ContentObserverController.get(this));
 
         mHandler = new JobHandler(context.getMainLooper());
         mJobSchedulerStub = new JobSchedulerStub();
@@ -461,7 +473,7 @@
                     JobStatus job = jobs.valueAt(i);
                     for (int controller=0; controller<mControllers.size(); controller++) {
                         mControllers.get(controller).deviceIdleModeChanged(mDeviceIdleMode);
-                        mControllers.get(controller).maybeStartTrackingJob(job);
+                        mControllers.get(controller).maybeStartTrackingJob(job, null);
                     }
                 }
                 // GO GO GO!
@@ -475,7 +487,7 @@
      * {@link com.android.server.job.JobStore}, and make sure all the relevant controllers know
      * about.
      */
-    private void startTrackingJob(JobStatus jobStatus) {
+    private void startTrackingJob(JobStatus jobStatus, JobStatus lastJob) {
         boolean update;
         boolean rocking;
         synchronized (mJobs) {
@@ -486,9 +498,9 @@
             for (int i=0; i<mControllers.size(); i++) {
                 StateController controller = mControllers.get(i);
                 if (update) {
-                    controller.maybeStopTrackingJob(jobStatus);
+                    controller.maybeStopTrackingJob(jobStatus, true);
                 }
-                controller.maybeStartTrackingJob(jobStatus);
+                controller.maybeStartTrackingJob(jobStatus, lastJob);
             }
         }
     }
@@ -508,7 +520,7 @@
         if (removed && rocking) {
             for (int i=0; i<mControllers.size(); i++) {
                 StateController controller = mControllers.get(i);
-                controller.maybeStopTrackingJob(jobStatus);
+                controller.maybeStopTrackingJob(jobStatus, false);
             }
         }
         return removed;
@@ -577,8 +589,13 @@
         }
         delayMillis =
                 Math.min(delayMillis, JobInfo.MAX_BACKOFF_DELAY_MILLIS);
-        return new JobStatus(failureToReschedule, elapsedNowMillis + delayMillis,
+        JobStatus newJob = new JobStatus(failureToReschedule, elapsedNowMillis + delayMillis,
                 JobStatus.NO_LATEST_RUNTIME, backoffAttempts);
+        for (int ic=0; ic<mControllers.size(); ic++) {
+            StateController controller = mControllers.get(ic);
+            controller.rescheduleForFailure(newJob, failureToReschedule);
+        }
+        return newJob;
     }
 
     /**
@@ -632,14 +649,21 @@
             if (DEBUG) {
                 Slog.d(TAG, "Could not find job to remove. Was job removed while executing?");
             }
+            // We still want to check for jobs to execute, because this job may have
+            // scheduled a new job under the same job id, and now we can run it.
+            mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
             return;
         }
+        // Note: there is a small window of time in here where, when rescheduling a job,
+        // we will stop monitoring its content providers.  This should be fixed by stopping
+        // the old job after scheduling the new one, but since we have no lock held here
+        // that may cause ordering problems if the app removes jobStatus while in here.
         if (needsReschedule) {
             JobStatus rescheduled = getRescheduleJobForFailure(jobStatus);
-            startTrackingJob(rescheduled);
+            startTrackingJob(rescheduled, jobStatus);
         } else if (jobStatus.getJob().isPeriodic()) {
             JobStatus rescheduledPeriodic = getRescheduleJobForPeriodic(jobStatus);
-            startTrackingJob(rescheduledPeriodic);
+            startTrackingJob(rescheduledPeriodic, jobStatus);
         }
         reportActive();
         mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
@@ -760,8 +784,10 @@
             int idleCount =  0;
             int backoffCount = 0;
             int connectivityCount = 0;
+            int contentCount = 0;
             List<JobStatus> runnableJobs = null;
             ArraySet<JobStatus> jobs = mJobs.getJobs();
+            if (DEBUG) Slog.d(TAG, "Maybe queuing ready jobs...");
             for (int i=0; i<jobs.size(); i++) {
                 JobStatus job = jobs.valueAt(i);
                 if (isReadyToBeExecutedLocked(job)) {
@@ -788,6 +814,9 @@
                     if (job.hasChargingConstraint()) {
                         chargingCount++;
                     }
+                    if (job.hasContentTriggerConstraint()) {
+                        contentCount++;
+                    }
                     if (runnableJobs == null) {
                         runnableJobs = new ArrayList<>();
                     }
@@ -801,6 +830,7 @@
                     idleCount >= MIN_IDLE_COUNT ||
                     connectivityCount >= MIN_CONNECTIVITY_COUNT ||
                     chargingCount >= MIN_CHARGING_COUNT ||
+                    contentCount  >= MIN_CONTENT_COUNT ||
                     (runnableJobs != null && runnableJobs.size() >= MIN_READY_JOBS_COUNT)) {
                 if (DEBUG) {
                     Slog.d(TAG, "maybeQueueReadyJobsForExecutionLockedH: Running jobs.");
@@ -953,6 +983,10 @@
                         Slog.d(TAG, "About to run job on context "
                                 + String.valueOf(i) + ", job: " + contextIdToJobMap[i]);
                     }
+                    for (int ic=0; ic<mControllers.size(); ic++) {
+                        StateController controller = mControllers.get(ic);
+                        controller.prepareForExecution(contextIdToJobMap[i]);
+                    }
                     if (!mActiveServices.get(i).executeRunnableJob(contextIdToJobMap[i])) {
                         Slog.d(TAG, "Error executing " + contextIdToJobMap[i]);
                     }
@@ -1162,7 +1196,20 @@
                 ArraySet<JobStatus> jobs = mJobs.getJobs();
                 for (int i=0; i<jobs.size(); i++) {
                     JobStatus job = jobs.valueAt(i);
-                    job.dump(pw, "  ");
+                    pw.print("  Job #"); pw.print(i); pw.print(": ");
+                    pw.println(job.toShortString());
+                    job.dump(pw, "    ");
+                    pw.print("    Ready: ");
+                    pw.print(mHandler.isReadyToBeExecutedLocked(job));
+                    pw.print(" (job=");
+                    pw.print(job.isReady());
+                    pw.print(" pending=");
+                    pw.print(mPendingJobs.contains(job));
+                    pw.print(" active=");
+                    pw.print(isCurrentlyActiveLocked(job));
+                    pw.print(" user=");
+                    pw.print(mStartedUsers.contains(job.getUserId()));
+                    pw.println(")");
                 }
             } else {
                 pw.println("  None.");
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index dd634fa..b249739 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -25,6 +25,7 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -170,7 +171,18 @@
             final boolean isDeadlineExpired =
                     job.hasDeadlineConstraint() &&
                             (job.getLatestRunTimeElapsed() < SystemClock.elapsedRealtime());
-            mParams = new JobParameters(this, job.getJobId(), job.getExtras(), isDeadlineExpired);
+            Uri[] triggeredUris = null;
+            if (job.changedUris != null) {
+                triggeredUris = new Uri[job.changedUris.size()];
+                job.changedUris.toArray(triggeredUris);
+            }
+            String[] triggeredAuthorities = null;
+            if (job.changedAuthorities != null) {
+                triggeredAuthorities = new String[job.changedAuthorities.size()];
+                job.changedAuthorities.toArray(triggeredAuthorities);
+            }
+            mParams = new JobParameters(this, job.getJobId(), job.getExtras(), isDeadlineExpired,
+                    triggeredUris, triggeredAuthorities);
             mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();
 
             mVerb = VERB_BINDING;
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index c88f5d7..f796164 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -187,9 +187,8 @@
      */
     public List<JobStatus> getJobsByUser(int userHandle) {
         List<JobStatus> matchingJobs = new ArrayList<JobStatus>();
-        Iterator<JobStatus> it = mJobSet.iterator();
-        while (it.hasNext()) {
-            JobStatus ts = it.next();
+        for (int i=mJobSet.size()-1; i>=0; i--) {
+            JobStatus ts = mJobSet.valueAt(i);
             if (UserHandle.getUserId(ts.getUid()) == userHandle) {
                 matchingJobs.add(ts);
             }
@@ -203,9 +202,8 @@
      */
     public List<JobStatus> getJobsByUid(int uid) {
         List<JobStatus> matchingJobs = new ArrayList<JobStatus>();
-        Iterator<JobStatus> it = mJobSet.iterator();
-        while (it.hasNext()) {
-            JobStatus ts = it.next();
+        for (int i=mJobSet.size()-1; i>=0; i--) {
+            JobStatus ts = mJobSet.valueAt(i);
             if (ts.getUid() == uid) {
                 matchingJobs.add(ts);
             }
@@ -219,9 +217,8 @@
      * @return the JobStatus that matches the provided uId and jobId, or null if none found.
      */
     public JobStatus getJobByUidAndJobId(int uid, int jobId) {
-        Iterator<JobStatus> it = mJobSet.iterator();
-        while (it.hasNext()) {
-            JobStatus ts = it.next();
+        for (int i=mJobSet.size()-1; i>=0; i--) {
+            JobStatus ts = mJobSet.valueAt(i);
             if (ts.getUid() == uid && ts.getJobId() == jobId) {
                 return ts;
             }
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index c09e06c..5f3da75 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -62,7 +62,7 @@
     }
 
     @Override
-    public void maybeStartTrackingJob(JobStatus jobStatus) {
+    public void maybeStartTrackingJob(JobStatus jobStatus, JobStatus lastJob) {
         synchronized (mTrackedTasks) {
             mTrackedTasks.add(jobStatus);
             String packageName = jobStatus.getSourcePackageName();
@@ -77,7 +77,7 @@
     }
 
     @Override
-    public void maybeStopTrackingJob(JobStatus jobStatus) {
+    public void maybeStopTrackingJob(JobStatus jobStatus, boolean forUpdate) {
         synchronized (mTrackedTasks) {
             mTrackedTasks.remove(jobStatus);
         }
diff --git a/services/core/java/com/android/server/job/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java
index 7c2aead..b322a3e 100644
--- a/services/core/java/com/android/server/job/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -16,8 +16,6 @@
 
 package com.android.server.job.controllers;
 
-import android.app.AlarmManager;
-import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -79,7 +77,7 @@
     }
 
     @Override
-    public void maybeStartTrackingJob(JobStatus taskStatus) {
+    public void maybeStartTrackingJob(JobStatus taskStatus, JobStatus lastJob) {
         final boolean isOnStablePower = mChargeTracker.isOnStablePower();
         if (taskStatus.hasChargingConstraint()) {
             synchronized (mTrackedTasks) {
@@ -90,7 +88,7 @@
     }
 
     @Override
-    public void maybeStopTrackingJob(JobStatus taskStatus) {
+    public void maybeStopTrackingJob(JobStatus taskStatus, boolean forUpdate) {
         if (taskStatus.hasChargingConstraint()) {
             synchronized (mTrackedTasks) {
                 mTrackedTasks.remove(taskStatus);
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index daba0d9..b84658a 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -82,7 +82,7 @@
     }
 
     @Override
-    public void maybeStartTrackingJob(JobStatus jobStatus) {
+    public void maybeStartTrackingJob(JobStatus jobStatus, JobStatus lastJob) {
         if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()) {
             synchronized (mTrackedJobs) {
                 jobStatus.connectivityConstraintSatisfied.set(mNetworkConnected);
@@ -93,7 +93,7 @@
     }
 
     @Override
-    public void maybeStopTrackingJob(JobStatus jobStatus) {
+    public void maybeStopTrackingJob(JobStatus jobStatus, boolean forUpdate) {
         if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()) {
             synchronized (mTrackedJobs) {
                 mTrackedJobs.remove(jobStatus);
diff --git a/services/core/java/com/android/server/job/controllers/ContentObserverController.java b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
new file mode 100644
index 0000000..212cc94
--- /dev/null
+++ b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job.controllers;
+
+import android.app.job.JobInfo;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Controller for monitoring changes to content URIs through a ContentObserver.
+ */
+public class ContentObserverController extends StateController {
+    private static final String TAG = "JobScheduler.Content";
+
+    /**
+     * Maximum number of changing URIs we will batch together to report.
+     * XXX Should be smarter about this, restricting it by the maximum number
+     * of characters we will retain.
+     */
+    private static final int MAX_URIS_REPORTED = 50;
+
+    private static final Object sCreationLock = new Object();
+    private static volatile ContentObserverController sController;
+
+    final private List<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
+    ArrayMap<Uri, ObserverInstance> mObservers = new ArrayMap<>();
+    final Handler mHandler = new Handler();
+
+    public static ContentObserverController get(JobSchedulerService taskManagerService) {
+        synchronized (sCreationLock) {
+            if (sController == null) {
+                sController = new ContentObserverController(taskManagerService,
+                        taskManagerService.getContext());
+            }
+        }
+        return sController;
+    }
+
+    @VisibleForTesting
+    public static ContentObserverController getForTesting(StateChangedListener stateChangedListener,
+                                           Context context) {
+        return new ContentObserverController(stateChangedListener, context);
+    }
+
+    private ContentObserverController(StateChangedListener stateChangedListener, Context context) {
+        super(stateChangedListener, context);
+    }
+
+    @Override
+    public void maybeStartTrackingJob(JobStatus taskStatus, JobStatus lastJob) {
+        if (taskStatus.hasContentTriggerConstraint()) {
+            synchronized (mTrackedTasks) {
+                if (taskStatus.contentObserverJobInstance == null) {
+                    taskStatus.contentObserverJobInstance = new JobInstance(taskStatus);
+                }
+                mTrackedTasks.add(taskStatus);
+                boolean havePendingUris = false;
+                // If there is a previous job associated with the new job, propagate over
+                // any pending content URI trigger reports.
+                if (lastJob != null && lastJob.contentObserverJobInstance != null
+                        && lastJob.contentObserverJobInstance
+                        != taskStatus.contentObserverJobInstance
+                        && lastJob.contentObserverJobInstance.mChangedAuthorities != null) {
+                    havePendingUris = true;
+                    taskStatus.contentObserverJobInstance.mChangedAuthorities
+                            = lastJob.contentObserverJobInstance.mChangedAuthorities;
+                    taskStatus.contentObserverJobInstance.mChangedUris
+                            = lastJob.contentObserverJobInstance.mChangedUris;
+                    lastJob.contentObserverJobInstance.mChangedAuthorities = null;
+                    lastJob.contentObserverJobInstance.mChangedUris = null;
+                }
+                // If we have previously reported changed authorities/uris, then we failed
+                // to complete the job with them so will re-record them to report again.
+                if (taskStatus.changedAuthorities != null) {
+                    havePendingUris = true;
+                    if (taskStatus.contentObserverJobInstance.mChangedAuthorities == null) {
+                        taskStatus.contentObserverJobInstance.mChangedAuthorities
+                                = new ArraySet<>();
+                    }
+                    for (String auth : taskStatus.changedAuthorities) {
+                        taskStatus.contentObserverJobInstance.mChangedAuthorities.add(auth);
+                    }
+                    if (taskStatus.changedUris != null) {
+                        if (taskStatus.contentObserverJobInstance.mChangedUris == null) {
+                            taskStatus.contentObserverJobInstance.mChangedUris = new ArraySet<>();
+                        }
+                        for (Uri uri : taskStatus.changedUris) {
+                            taskStatus.contentObserverJobInstance.mChangedUris.add(uri);
+                        }
+                    }
+                    taskStatus.changedAuthorities = null;
+                    taskStatus.changedUris = null;
+                }
+                taskStatus.changedAuthorities = null;
+                taskStatus.changedUris = null;
+                taskStatus.contentTriggerConstraintSatisfied.set(havePendingUris);
+            }
+        }
+    }
+
+    @Override
+    public void prepareForExecution(JobStatus taskStatus) {
+        if (taskStatus.hasContentTriggerConstraint()) {
+            synchronized (mTrackedTasks) {
+                if (taskStatus.contentObserverJobInstance != null) {
+                    taskStatus.changedUris = taskStatus.contentObserverJobInstance.mChangedUris;
+                    taskStatus.changedAuthorities
+                            = taskStatus.contentObserverJobInstance.mChangedAuthorities;
+                    taskStatus.contentObserverJobInstance.mChangedUris = null;
+                    taskStatus.contentObserverJobInstance.mChangedAuthorities = null;
+                }
+            }
+        }
+    }
+
+    @Override
+    public void maybeStopTrackingJob(JobStatus taskStatus, boolean forUpdate) {
+        if (taskStatus.hasContentTriggerConstraint()) {
+            synchronized (mTrackedTasks) {
+                if (!forUpdate) {
+                    // We won't do this reset if being called for an update, because
+                    // we know it will be immediately followed by maybeStartTrackingJob...
+                    // and we don't want to lose any content changes in-between.
+                    if (taskStatus.contentObserverJobInstance != null) {
+                        taskStatus.contentObserverJobInstance.detach();
+                        taskStatus.contentObserverJobInstance = null;
+                    }
+                }
+                mTrackedTasks.remove(taskStatus);
+            }
+        }
+    }
+
+    @Override
+    public void rescheduleForFailure(JobStatus newJob, JobStatus failureToReschedule) {
+        if (failureToReschedule.hasContentTriggerConstraint()
+                && newJob.hasContentTriggerConstraint()) {
+            synchronized (mTrackedTasks) {
+                // Our job has failed, and we are scheduling a new job for it.
+                // Copy the last reported content changes in to the new job, so when
+                // we schedule the new one we will pick them up and report them again.
+                newJob.changedAuthorities = failureToReschedule.changedAuthorities;
+                newJob.changedUris = failureToReschedule.changedUris;
+            }
+        }
+    }
+
+    class ObserverInstance extends ContentObserver {
+        final Uri mUri;
+        final ArrayList<JobInstance> mJobs = new ArrayList<>();
+
+        public ObserverInstance(Handler handler, Uri uri) {
+            super(handler);
+            mUri = uri;
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            boolean reportChange = false;
+            synchronized (mTrackedTasks) {
+                final int N = mJobs.size();
+                for (int i=0; i<N; i++) {
+                    JobInstance inst = mJobs.get(i);
+                    if (inst.mChangedUris == null) {
+                        inst.mChangedUris = new ArraySet<>();
+                    }
+                    if (inst.mChangedUris.size() < MAX_URIS_REPORTED) {
+                        inst.mChangedUris.add(uri);
+                    }
+                    if (inst.mChangedAuthorities == null) {
+                        inst.mChangedAuthorities = new ArraySet<>();
+                    }
+                    inst.mChangedAuthorities.add(uri.getAuthority());
+                    boolean previous
+                            = inst.mJobStatus.contentTriggerConstraintSatisfied.getAndSet(true);
+                    if (!previous) {
+                        reportChange = true;
+                    }
+                }
+            }
+            // Let the scheduler know that state has changed. This may or may not result in an
+            // execution.
+            if (reportChange) {
+                mStateChangedListener.onControllerStateChanged();
+            }
+        }
+    }
+
+    class JobInstance extends ArrayList<ObserverInstance> {
+        private final JobStatus mJobStatus;
+        private ArraySet<Uri> mChangedUris;
+        private ArraySet<String> mChangedAuthorities;
+
+        JobInstance(JobStatus jobStatus) {
+            mJobStatus = jobStatus;
+            final JobInfo.TriggerContentUri[] uris = jobStatus.getJob().getTriggerContentUris();
+            if (uris != null) {
+                for (JobInfo.TriggerContentUri uri : uris) {
+                    ObserverInstance obs = mObservers.get(uri.getUri());
+                    if (obs == null) {
+                        obs = new ObserverInstance(mHandler, uri.getUri());
+                        mObservers.put(uri.getUri(), obs);
+                        mContext.getContentResolver().registerContentObserver(
+                                uri.getUri(),
+                                (uri.getFlags() &
+                                        JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)
+                                    != 0,
+                                obs);
+                    }
+                    obs.mJobs.add(this);
+                    add(obs);
+                }
+            }
+        }
+
+        void detach() {
+            final int N = size();
+            for (int i=0; i<N; i++) {
+                final ObserverInstance obs = get(i);
+                obs.mJobs.remove(this);
+                if (obs.mJobs.size() == 0) {
+                    mContext.getContentResolver().unregisterContentObserver(obs);
+                    mObservers.remove(obs.mUri);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void dumpControllerState(PrintWriter pw) {
+        pw.println("Content.");
+        synchronized (mTrackedTasks) {
+            Iterator<JobStatus> it = mTrackedTasks.iterator();
+            if (it.hasNext()) {
+                pw.print(String.valueOf(it.next().hashCode()));
+            }
+            while (it.hasNext()) {
+                pw.print("," + String.valueOf(it.next().hashCode()));
+            }
+            pw.println();
+            int N = mObservers.size();
+            if (N > 0) {
+                pw.println("URIs:");
+                for (int i = 0; i < N; i++) {
+                    ObserverInstance obs = mObservers.valueAt(i);
+                    pw.print("  ");
+                    pw.print(mObservers.keyAt(i));
+                    pw.println(":");
+                    pw.print("    ");
+                    pw.println(obs);
+                    pw.println("    Jobs:");
+                    int M = obs.mJobs.size();
+                    for (int j=0; j<M; j++) {
+                        JobInstance inst = obs.mJobs.get(j);
+                        pw.print("      ");
+                        pw.print(inst.hashCode());
+                        if (inst.mChangedAuthorities != null) {
+                            pw.println(":");
+                            pw.println("        Changed Authorities:");
+                            for (int k=0; k<inst.mChangedAuthorities.size(); k++) {
+                                pw.print("          ");
+                                pw.println(inst.mChangedAuthorities.valueAt(k));
+                            }
+                            if (inst.mChangedUris != null) {
+                                pw.println("        Changed URIs:");
+                                for (int k = 0; k<inst.mChangedUris.size(); k++) {
+                                    pw.print("          ");
+                                    pw.println(inst.mChangedUris.valueAt(k));
+                                }
+                            }
+                        } else {
+                            pw.println();
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index fe5e8c9..9f4cdef 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -66,7 +66,7 @@
      * StateController interface
      */
     @Override
-    public void maybeStartTrackingJob(JobStatus taskStatus) {
+    public void maybeStartTrackingJob(JobStatus taskStatus, JobStatus lastJob) {
         if (taskStatus.hasIdleConstraint()) {
             synchronized (mTrackedTasks) {
                 mTrackedTasks.add(taskStatus);
@@ -76,7 +76,7 @@
     }
 
     @Override
-    public void maybeStopTrackingJob(JobStatus taskStatus) {
+    public void maybeStopTrackingJob(JobStatus taskStatus, boolean forUpdate) {
         synchronized (mTrackedTasks) {
             mTrackedTasks.remove(taskStatus);
         }
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 e6e9e49..4113180 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -19,11 +19,14 @@
 import android.app.AppGlobals;
 import android.app.job.JobInfo;
 import android.content.ComponentName;
+import android.net.Uri;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.text.format.DateUtils;
+import android.util.ArraySet;
+import android.util.TimeUtils;
 
 import java.io.PrintWriter;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -61,6 +64,17 @@
     final AtomicBoolean unmeteredConstraintSatisfied = new AtomicBoolean();
     final AtomicBoolean connectivityConstraintSatisfied = new AtomicBoolean();
     final AtomicBoolean appNotIdleConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean contentTriggerConstraintSatisfied = new AtomicBoolean();
+
+    // These are filled in by controllers when preparing for execution.
+    public ArraySet<Uri> changedUris;
+    public ArraySet<String> changedAuthorities;
+
+    /**
+     * For use only by ContentObserverController: state it is maintaining about content URIs
+     * being observed.
+     */
+    ContentObserverController.JobInstance contentObserverJobInstance;
 
     /**
      * Earliest point in the future at which this job will be eligible to run. A value of 0
@@ -220,6 +234,10 @@
         return job.isRequireDeviceIdle();
     }
 
+    public boolean hasContentTriggerConstraint() {
+        return job.getTriggerContentUris() != null;
+    }
+
     public boolean isPersisted() {
         return job.isPersisted();
     }
@@ -252,7 +270,8 @@
                 && (!hasTimingDelayConstraint() || timeDelayConstraintSatisfied.get())
                 && (!hasConnectivityConstraint() || connectivityConstraintSatisfied.get())
                 && (!hasUnmeteredConstraint() || unmeteredConstraintSatisfied.get())
-                && (!hasIdleConstraint() || idleConstraintSatisfied.get());
+                && (!hasIdleConstraint() || idleConstraintSatisfied.get())
+                && (!hasContentTriggerConstraint() || contentTriggerConstraintSatisfied.get());
     }
 
     public boolean matches(int uid, int jobId) {
@@ -268,8 +287,9 @@
                 + ",R=(" + formatRunTime(earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME)
                 + "," + formatRunTime(latestRunTimeElapsedMillis, NO_LATEST_RUNTIME) + ")"
                 + ",N=" + job.getNetworkType() + ",C=" + job.isRequireCharging()
-                + ",I=" + job.isRequireDeviceIdle() + ",F=" + numFailures
-                + ",P=" + job.isPersisted()
+                + ",I=" + job.isRequireDeviceIdle()
+                + ",U=" + (job.getTriggerContentUris() != null)
+                + ",F=" + numFailures + ",P=" + job.isPersisted()
                 + ",ANI=" + appNotIdleConstraintSatisfied.get()
                 + (isReady() ? "(READY)" : "")
                 + "]";
@@ -310,13 +330,132 @@
      * {@link #toString()} returns.
      */
     public String toShortString() {
-        return job.getService().flattenToShortString() + " jId=" + job.getId() +
-                ", u" + getUserId();
+        StringBuilder sb = new StringBuilder();
+        sb.append(Integer.toHexString(System.identityHashCode(this)));
+        sb.append(" jId=");
+        sb.append(job.getId());
+        sb.append(" uid=");
+        UserHandle.formatUid(sb, uId);
+        sb.append(' ');
+        sb.append(job.getService().flattenToShortString());
+        return sb.toString();
     }
 
     // Dumpsys infrastructure
     public void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); UserHandle.formatUid(pw, uId);
+        pw.print(" tag="); pw.println(tag);
         pw.print(prefix);
-        pw.println(this.toString());
+        pw.print("Source: uid="); UserHandle.formatUid(pw, sourceUid);
+        pw.print(" user="); pw.print(sourceUserId);
+        pw.print(" pkg="); pw.println(sourcePackageName);
+        pw.print(prefix); pw.println("JobInfo:");
+        pw.print(prefix); pw.print("  Service: ");
+        pw.println(job.getService().flattenToShortString());
+        if (job.isPeriodic()) {
+            pw.print(prefix); pw.print("  PERIODIC: interval=");
+            TimeUtils.formatDuration(job.getIntervalMillis(), pw);
+            pw.print(" flex=");
+            TimeUtils.formatDuration(job.getFlexMillis(), pw);
+            pw.println();
+        }
+        if (job.isPersisted()) {
+            pw.print(prefix); pw.println("  PERSISTED");
+        }
+        if (job.getPriority() != 0) {
+            pw.print(prefix); pw.print("  Priority: ");
+            pw.println(job.getPriority());
+        }
+        pw.print(prefix); pw.print("  Requires: charging=");
+        pw.print(job.isRequireCharging());
+        pw.print(" deviceIdle=");
+        pw.println(job.isRequireDeviceIdle());
+        if (job.getTriggerContentUris() != null) {
+            pw.print(prefix); pw.println("  Trigger content URIs:");
+            for (int i=0; i<job.getTriggerContentUris().length; i++) {
+                JobInfo.TriggerContentUri trig = job.getTriggerContentUris()[i];
+                pw.print(prefix); pw.print("    ");
+                pw.print(Integer.toHexString(trig.getFlags()));
+                pw.print(' ' );
+                pw.println(trig.getUri());
+            }
+        }
+        if (job.getNetworkType() != JobInfo.NETWORK_TYPE_NONE) {
+            pw.print(prefix); pw.print("  Network type: ");
+            pw.println(job.getNetworkType());
+        }
+        if (job.getMinLatencyMillis() != 0) {
+            pw.print(prefix); pw.print("  Minimum latency: ");
+            TimeUtils.formatDuration(job.getMinLatencyMillis(), pw);
+            pw.println();
+        }
+        if (job.getMaxExecutionDelayMillis() != 0) {
+            pw.print(prefix); pw.print("  Max execution delay: ");
+            TimeUtils.formatDuration(job.getMaxExecutionDelayMillis(), pw);
+            pw.println();
+        }
+        pw.print(prefix); pw.print("  Backoff: policy=");
+        pw.print(job.getBackoffPolicy());
+        pw.print(" initial=");
+        TimeUtils.formatDuration(job.getInitialBackoffMillis(), pw);
+        pw.println();
+        if (job.hasEarlyConstraint()) {
+            pw.print(prefix); pw.println("  Has early constraint");
+        }
+        if (job.hasLateConstraint()) {
+            pw.print(prefix); pw.println("  Has late constraint");
+        }
+        pw.print(prefix); pw.println("Constraints:");
+        if (hasChargingConstraint()) {
+            pw.print(prefix); pw.print("  Charging: ");
+            pw.println(chargingConstraintSatisfied.get());
+        }
+        if (hasTimingDelayConstraint()) {
+            pw.print(prefix); pw.print("  Time delay: ");
+            pw.println(timeDelayConstraintSatisfied.get());
+        }
+        if (hasDeadlineConstraint()) {
+            pw.print(prefix); pw.print("  Deadline: ");
+            pw.println(deadlineConstraintSatisfied.get());
+        }
+        if (hasIdleConstraint()) {
+            pw.print(prefix); pw.print("  System idle: ");
+            pw.println(idleConstraintSatisfied.get());
+        }
+        if (hasUnmeteredConstraint()) {
+            pw.print(prefix); pw.print("  Unmetered: ");
+            pw.println(unmeteredConstraintSatisfied.get());
+        }
+        if (hasConnectivityConstraint()) {
+            pw.print(prefix); pw.print("  Connectivity: ");
+            pw.println(connectivityConstraintSatisfied.get());
+        }
+        if (hasIdleConstraint()) {
+            pw.print(prefix); pw.print("  App not idle: ");
+            pw.println(appNotIdleConstraintSatisfied.get());
+        }
+        if (hasContentTriggerConstraint()) {
+            pw.print(prefix); pw.print("  Content trigger: ");
+            pw.println(contentTriggerConstraintSatisfied.get());
+        }
+        if (changedAuthorities != null) {
+            pw.print(prefix); pw.println("Changed authorities:");
+            for (int i=0; i<changedAuthorities.size(); i++) {
+                pw.print(prefix); pw.print("  "); pw.println(changedAuthorities.valueAt(i));
+            }
+            if (changedUris != null) {
+                pw.print(prefix); pw.println("Changed URIs:");
+                for (int i=0; i<changedUris.size(); i++) {
+                    pw.print(prefix); pw.print("  "); pw.println(changedUris.valueAt(i));
+                }
+            }
+        }
+        pw.print(prefix); pw.print("Earliest run time: ");
+        pw.println(formatRunTime(earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME));
+        pw.print(prefix); pw.print("Latest run time: ");
+        pw.println(formatRunTime(latestRunTimeElapsedMillis, NO_LATEST_RUNTIME));
+        if (numFailures != 0) {
+            pw.print(prefix); pw.print("Num failures: "); pw.println(numFailures);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java
index 21c30c7..b619ea8 100644
--- a/services/core/java/com/android/server/job/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -49,11 +49,21 @@
      * Also called when updating a task, so implementing controllers have to be aware of
      * preexisting tasks.
      */
-    public abstract void maybeStartTrackingJob(JobStatus jobStatus);
+    public abstract void maybeStartTrackingJob(JobStatus jobStatus, JobStatus lastJob);
+    /**
+     * Optionally implement logic here to prepare the job to be executed.
+     */
+    public void prepareForExecution(JobStatus jobStatus) {
+    }
     /**
      * Remove task - this will happen if the task is cancelled, completed, etc.
      */
-    public abstract void maybeStopTrackingJob(JobStatus jobStatus);
+    public abstract void maybeStopTrackingJob(JobStatus jobStatus, boolean forUpdate);
+    /**
+     * Called when a new job is being created to reschedule an old failed job.
+     */
+    public void rescheduleForFailure(JobStatus newJob, JobStatus failureToReschedule) {
+    }
 
     public abstract void dumpControllerState(PrintWriter pw);
 }
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index 854ce31..a68c3ad 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -71,9 +71,9 @@
      * list.
      */
     @Override
-    public synchronized void maybeStartTrackingJob(JobStatus job) {
+    public synchronized void maybeStartTrackingJob(JobStatus job, JobStatus lastJob) {
         if (job.hasTimingDelayConstraint() || job.hasDeadlineConstraint()) {
-            maybeStopTrackingJob(job);
+            maybeStopTrackingJob(job, false);
             boolean isInsert = false;
             ListIterator<JobStatus> it = mTrackedJobs.listIterator(mTrackedJobs.size());
             while (it.hasPrevious()) {
@@ -101,7 +101,7 @@
      * Really an == comparison should be enough, but why play with fate? We'll do <=.
      */
     @Override
-    public synchronized void maybeStopTrackingJob(JobStatus job) {
+    public synchronized void maybeStopTrackingJob(JobStatus job, boolean forUpdate) {
         if (mTrackedJobs.remove(job)) {
             checkExpiredDelaysAndResetAlarm();
             checkExpiredDeadlinesAndResetAlarm();
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 1d7d24b..492632c 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1155,7 +1155,7 @@
         final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length);
         final ArraySet<String> connIfaces = new ArraySet<String>(states.length);
         for (NetworkState state : states) {
-            if (state.networkInfo.isConnected()) {
+            if (state.networkInfo != null && state.networkInfo.isConnected()) {
                 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
 
                 final String baseIface = state.linkProperties.getInterfaceName();
@@ -1990,6 +1990,10 @@
         if (policy != null) {
             return policy.metered;
         } else {
+            if (state.networkInfo == null) {
+                return false;
+            }
+
             final int type = state.networkInfo.getType();
             if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) {
                 return true;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 2ee74db..b54efcc 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -16,6 +16,7 @@
 
 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;
@@ -28,6 +29,7 @@
 import static android.service.notification.NotificationAssistantService.REASON_LISTENER_CANCEL_ALL;
 import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_BANNED;
 import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_CHANGED;
+import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_SUSPENDED;
 import static android.service.notification.NotificationAssistantService.REASON_TOPIC_BANNED;
 import static android.service.notification.NotificationAssistantService.REASON_USER_STOPPED;
 import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
@@ -456,7 +458,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;
+                == AppOpsManager.MODE_ALLOWED && !isApplicationSuspended(pkg, uid);
     }
 
     private static final class ToastRecord
@@ -691,13 +693,15 @@
             boolean queryRemove = false;
             boolean packageChanged = false;
             boolean cancelNotifications = true;
+            int reason = REASON_PACKAGE_CHANGED;
 
             if (action.equals(Intent.ACTION_PACKAGE_ADDED)
                     || (queryRemove=action.equals(Intent.ACTION_PACKAGE_REMOVED))
                     || action.equals(Intent.ACTION_PACKAGE_RESTARTED)
                     || (packageChanged=action.equals(Intent.ACTION_PACKAGE_CHANGED))
                     || (queryRestart=action.equals(Intent.ACTION_QUERY_PACKAGE_RESTART))
-                    || action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
+                    || action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)
+                    || action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
                 int changeUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                         UserHandle.USER_ALL);
                 String pkgList[] = null;
@@ -706,6 +710,9 @@
                 if (DBG) Slog.i(TAG, "action=" + action + " queryReplace=" + queryReplace);
                 if (action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
                     pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+                } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
+                    pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+                    reason = REASON_PACKAGE_SUSPENDED;
                 } else if (queryRestart) {
                     pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
                 } else {
@@ -745,7 +752,7 @@
                     for (String pkgName : pkgList) {
                         if (cancelNotifications) {
                             cancelAllNotificationsInt(MY_UID, MY_PID, pkgName, 0, 0, !queryRestart,
-                                    changeUserId, REASON_PACKAGE_CHANGED, null, null);
+                                    changeUserId, reason, null, null);
                         }
                     }
                 }
@@ -989,6 +996,11 @@
         getContext().registerReceiverAsUser(mPackageIntentReceiver, UserHandle.ALL, pkgFilter, null,
                 null);
 
+        IntentFilter suspendedPkgFilter = new IntentFilter();
+        suspendedPkgFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
+        getContext().registerReceiverAsUser(mPackageIntentReceiver, UserHandle.ALL,
+                suspendedPkgFilter, null, null);
+
         IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
         getContext().registerReceiverAsUser(mPackageIntentReceiver, UserHandle.ALL, sdFilter, null,
                 null);
@@ -1104,10 +1116,16 @@
             }
 
             final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg));
+            final boolean isApplicationSuspended =
+                    isApplicationSuspended(pkg, Binder.getCallingUid());
 
-            if (ENABLE_BLOCKED_TOASTS && !noteNotificationOp(pkg, Binder.getCallingUid())) {
+            if (ENABLE_BLOCKED_TOASTS && (!noteNotificationOp(pkg, Binder.getCallingUid())
+                    || isApplicationSuspended)) {
                 if (!isSystemToast) {
-                    Slog.e(TAG, "Suppressing toast from package " + pkg + " by user request.");
+                    Slog.e(TAG, "Suppressing toast from package " + pkg
+                            + (isApplicationSuspended
+                                    ? " due to package suspended by administrator."
+                                    : " by user request."));
                     return;
                 }
             }
@@ -1232,7 +1250,7 @@
         public boolean areNotificationsEnabledForPackage(String pkg, int uid) {
             checkCallerIsSystem();
             return (mAppOps.checkOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg)
-                    == AppOpsManager.MODE_ALLOWED);
+                    == AppOpsManager.MODE_ALLOWED) && !isApplicationSuspended(pkg, uid);
         }
 
         @Override
@@ -1242,58 +1260,55 @@
         }
 
         @Override
-        public void setTopicPriority(String pkg, int uid, Notification.Topic topic, int priority) {
+        public void setPriority(String pkg, int uid, Notification.Topic topic, int priority) {
             checkCallerIsSystem();
-            mRankingHelper.setTopicPriority(pkg, uid, topic, priority);
+            mRankingHelper.setPriority(pkg, uid, topic, priority);
             savePolicyFile();
         }
 
         @Override
-        public int getTopicPriority(String pkg, int uid, Notification.Topic topic) {
+        public int getPriority(String pkg, int uid, Notification.Topic topic) {
             checkCallerIsSystem();
-            return mRankingHelper.getTopicPriority(pkg, uid, topic);
+            return mRankingHelper.getPriority(pkg, uid, topic);
         }
 
         @Override
-        public void setTopicVisibilityOverride(String pkg, int uid, Notification.Topic topic,
+        public void setVisibilityOverride(String pkg, int uid, Notification.Topic topic,
                 int visibility) {
             checkCallerIsSystem();
-            mRankingHelper.setTopicVisibilityOverride(pkg, uid, topic, visibility);
+            mRankingHelper.setVisibilityOverride(pkg, uid, topic, visibility);
             savePolicyFile();
         }
 
         @Override
-        public int getTopicVisibilityOverride(String pkg, int uid, Notification.Topic topic) {
+        public int getVisibilityOverride(String pkg, int uid, Notification.Topic topic) {
             checkCallerIsSystem();
-            return mRankingHelper.getTopicVisibilityOverride(pkg, uid, topic);
+            return mRankingHelper.getVisibilityOverride(pkg, uid, topic);
         }
 
         @Override
-        public void setTopicImportance(String pkg, int uid, Notification.Topic topic,
+        public void setImportance(String pkg, int uid, Notification.Topic topic,
                 int importance) {
             enforceSystemOrSystemUI("Caller not system or systemui");
-            if (NotificationListenerService.Ranking.IMPORTANCE_NONE == importance) {
-                cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true,
-                        UserHandle.getUserId(uid),
-                        REASON_TOPIC_BANNED, topic, null);
+            if (topic == null) {
+                // App wide, potentially store block in app ops.
+                setNotificationsEnabledForPackageImpl(pkg, uid,
+                        importance != NotificationListenerService.Ranking.IMPORTANCE_NONE);
+            } else {
+                if (NotificationListenerService.Ranking.IMPORTANCE_NONE == importance) {
+                    cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true,
+                            UserHandle.getUserId(uid),
+                            REASON_TOPIC_BANNED, topic, null);
+                }
             }
-            mRankingHelper.setTopicImportance(pkg, uid, topic, importance);
+            mRankingHelper.setImportance(pkg, uid, topic, importance);
             savePolicyFile();
         }
 
         @Override
-        public int getTopicImportance(String pkg, int uid, Notification.Topic topic) {
+        public int getImportance(String pkg, int uid, Notification.Topic topic) {
             checkCallerIsSystem();
-            return mRankingHelper.getTopicImportance(pkg, uid, topic);
-        }
-
-        @Override
-        public void setAppImportance(String pkg, int uid, int importance) {
-            enforceSystemOrSystemUI("Caller not system or systemui");
-            setNotificationsEnabledForPackageImpl(pkg, uid,
-                    importance != NotificationListenerService.Ranking.IMPORTANCE_NONE);
-            mRankingHelper.setAppImportance(pkg, uid, importance);
-            savePolicyFile();
+            return mRankingHelper.getImportance(pkg, uid, topic);
         }
 
         @Override
@@ -2328,14 +2343,20 @@
 
                 // why is this here?
                 savePolicyFile();
+                final boolean isApplicationSuspended = isApplicationSuspended(pkg, callingUid);
 
                 // blocked apps/topics
                 if (r.getImportance() == NotificationListenerService.Ranking.IMPORTANCE_NONE
-                        || !noteNotificationOp(pkg, callingUid)) {
+                        || !noteNotificationOp(pkg, callingUid) || isApplicationSuspended) {
                     if (!isSystemNotification) {
-                        Slog.e(TAG, "Suppressing notification from package " + pkg
-                                + " by user request.");
-                        mUsageStats.registerBlocked(r);
+                        if (isApplicationSuspended) {
+                            Slog.e(TAG, "Suppressing notification from package due to package "
+                                    + "suspended by administrator.");
+                            mUsageStats.registerSuspendedByAdmin(r);
+                        } else {
+                            Slog.e(TAG, "Suppressing notification from package by user request.");
+                            mUsageStats.registerBlocked(r);
+                        }
                         return;
                     }
                 }
@@ -3426,6 +3447,24 @@
         return true;
     }
 
+    private boolean isApplicationSuspended(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;
+            }
+        } catch (RemoteException re) {
+            throw new SecurityException("Could not talk to package manager service");
+        }
+
+        return ((ai.flags & FLAG_SUSPENDED) != 0);
+    }
+
     private class TrimCache {
         StatusBarNotification heavy;
         StatusBarNotification sbnClone;
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 490e890..484b0e9 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -33,6 +33,7 @@
 import android.service.notification.StatusBarNotification;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
 import com.android.server.EventLogTags;
 
 import java.io.PrintWriter;
@@ -106,6 +107,7 @@
         mCreationTimeMs = sbn.getPostTime();
         mUpdateTimeMs = mCreationTimeMs;
         mContext = context;
+        stats = new NotificationUsageStats.SingleNotificationStats();
         mImportance = defaultImportance();
     }
 
@@ -133,27 +135,22 @@
                 importance = IMPORTANCE_MAX;
                 break;
         }
+        stats.requestedImportance = importance;
 
         boolean isNoisy = (n.defaults & Notification.DEFAULT_SOUND) != 0
                 || (n.defaults & Notification.DEFAULT_VIBRATE) != 0
                 || n.sound != null
                 || n.vibrate != null;
+        stats.isNoisy = isNoisy;
         if (!isNoisy && importance > IMPORTANCE_DEFAULT) {
             importance = IMPORTANCE_DEFAULT;
         }
-        // maybe only do this for target API < N?
-        if (isNoisy) {
-            if (importance >= IMPORTANCE_HIGH) {
-                importance = IMPORTANCE_MAX;
-            } else {
-                importance = IMPORTANCE_HIGH;
-            }
-        }
 
         if (n.fullScreenIntent != null) {
             importance = IMPORTANCE_MAX;
         }
 
+        stats.naturalImportance = importance;
         return importance;
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 1cdc6db..0272850 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -16,6 +16,8 @@
 
 package com.android.server.notification;
 
+import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH;
+
 import android.app.Notification;
 import android.content.ContentValues;
 import android.content.Context;
@@ -101,7 +103,6 @@
      * Called when a notification has been posted.
      */
     public synchronized void registerPostedByApp(NotificationRecord notification) {
-        notification.stats = new SingleNotificationStats();
         notification.stats.posttimeElapsedMs = SystemClock.elapsedRealtime();
 
         AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
@@ -119,13 +120,16 @@
      * Called when a notification has been updated.
      */
     public void registerUpdatedByApp(NotificationRecord notification, NotificationRecord old) {
-        notification.stats = old.stats;
+        notification.stats.updateFrom(old.stats);
         AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
         for (AggregatedStats stats : aggregatedStatsArray) {
             stats.numUpdatedByApp++;
             stats.countApiUse(notification);
         }
         releaseAggregatedStatsLocked(aggregatedStatsArray);
+        if (ENABLE_SQLITE_LOG) {
+            mSQLiteLog.logPosted(notification);
+        }
     }
 
     /**
@@ -194,6 +198,14 @@
         releaseAggregatedStatsLocked(aggregatedStatsArray);
     }
 
+    public synchronized void registerSuspendedByAdmin(NotificationRecord notification) {
+        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
+        for (AggregatedStats stats : aggregatedStatsArray) {
+            stats.numSuspendedByAdmin++;
+        }
+        releaseAggregatedStatsLocked(aggregatedStatsArray);
+    }
+
     // Locked by this.
     private AggregatedStats[] getAggregatedStatsLocked(NotificationRecord record) {
         if (!ENABLE_AGGREGATED_IN_MEMORY_STATS) {
@@ -294,13 +306,10 @@
         public int numWithStaredPeople;
         public int numWithValidPeople;
         public int numBlocked;
+        public int numSuspendedByAdmin;
         public int numWithActions;
         public int numPrivate;
         public int numSecret;
-        public int numPriorityMax;
-        public int numPriorityHigh;
-        public int numPriorityLow;
-        public int numPriorityMin;
         public int numWithBigText;
         public int numWithBigPicture;
         public int numForegroundService;
@@ -314,11 +323,17 @@
         public int numWithSubText;
         public int numWithInfoText;
         public int numInterrupt;
+        public ImportanceHistogram noisyImportance;
+        public ImportanceHistogram quietImportance;
+        public ImportanceHistogram finalImportance;
 
         public AggregatedStats(Context context, String key) {
             this.key = key;
             mContext = context;
             mCreated = SystemClock.elapsedRealtime();
+            noisyImportance = new ImportanceHistogram(context, "note_imp_noisy_");
+            quietImportance = new ImportanceHistogram(context, "note_imp_quiet_");
+            finalImportance = new ImportanceHistogram(context, "note_importance_");
         }
 
         public void countApiUse(NotificationRecord record) {
@@ -354,20 +369,12 @@
                     break;
             }
 
-            switch (n.priority) {
-                case Notification.PRIORITY_MAX:
-                    numPriorityMax++;
-                    break;
-                case Notification.PRIORITY_HIGH:
-                    numPriorityHigh++;
-                    break;
-                case Notification.PRIORITY_LOW:
-                    numPriorityLow++;
-                    break;
-                case Notification.PRIORITY_MIN:
-                    numPriorityMin++;
-                    break;
+            if (record.stats.isNoisy) {
+                noisyImportance.increment(record.stats.requestedImportance);
+            } else {
+                quietImportance.increment(record.stats.requestedImportance);
             }
+            finalImportance.increment(record.getImportance());
 
             final Set<String> names = n.extras.keySet();
             if (names.contains(Notification.EXTRA_BIG_TEXT)) {
@@ -416,13 +423,10 @@
             maybeCount("people_cache_hit", (numPeopleCacheHit - mPrevious.numPeopleCacheHit));
             maybeCount("people_cache_miss", (numPeopleCacheMiss - mPrevious.numPeopleCacheMiss));
             maybeCount("note_blocked", (numBlocked - mPrevious.numBlocked));
+            maybeCount("note_suspended", (numSuspendedByAdmin - mPrevious.numSuspendedByAdmin));
             maybeCount("note_with_actions", (numWithActions - mPrevious.numWithActions));
             maybeCount("note_private", (numPrivate - mPrevious.numPrivate));
             maybeCount("note_secret", (numSecret - mPrevious.numSecret));
-            maybeCount("note_prio_max", (numPriorityMax - mPrevious.numPriorityMax));
-            maybeCount("note_prio_high", (numPriorityHigh - mPrevious.numPriorityHigh));
-            maybeCount("note_prio_low", (numPriorityLow - mPrevious.numPriorityLow));
-            maybeCount("note_prio_min", (numPriorityMin - mPrevious.numPriorityMin));
             maybeCount("note_interupt", (numInterrupt - mPrevious.numInterrupt));
             maybeCount("note_big_text", (numWithBigText - mPrevious.numWithBigText));
             maybeCount("note_big_pic", (numWithBigPicture - mPrevious.numWithBigPicture));
@@ -436,6 +440,9 @@
             maybeCount("note_text", (numWithText - mPrevious.numWithText));
             maybeCount("note_sub_text", (numWithSubText - mPrevious.numWithSubText));
             maybeCount("note_info_text", (numWithInfoText - mPrevious.numWithInfoText));
+            noisyImportance.maybeCount(mPrevious.noisyImportance);
+            quietImportance.maybeCount(mPrevious.quietImportance);
+            finalImportance.maybeCount(mPrevious.finalImportance);
 
             mPrevious.numPostedByApp = numPostedByApp;
             mPrevious.numUpdatedByApp = numUpdatedByApp;
@@ -445,13 +452,10 @@
             mPrevious.numWithStaredPeople = numWithStaredPeople;
             mPrevious.numWithValidPeople = numWithValidPeople;
             mPrevious.numBlocked = numBlocked;
+            mPrevious.numSuspendedByAdmin = numSuspendedByAdmin;
             mPrevious.numWithActions = numWithActions;
             mPrevious.numPrivate = numPrivate;
             mPrevious.numSecret = numSecret;
-            mPrevious.numPriorityMax = numPriorityMax;
-            mPrevious.numPriorityHigh = numPriorityHigh;
-            mPrevious.numPriorityLow = numPriorityLow;
-            mPrevious.numPriorityMin = numPriorityMin;
             mPrevious.numInterrupt = numInterrupt;
             mPrevious.numWithBigText = numWithBigText;
             mPrevious.numWithBigPicture = numWithBigPicture;
@@ -465,6 +469,9 @@
             mPrevious.numWithText = numWithText;
             mPrevious.numWithSubText = numWithSubText;
             mPrevious.numWithInfoText = numWithInfoText;
+            noisyImportance.update(mPrevious.noisyImportance);
+            quietImportance.update(mPrevious.quietImportance);
+            finalImportance.update(mPrevious.finalImportance);
         }
 
         void maybeCount(String name, int value) {
@@ -483,17 +490,66 @@
         }
 
         private String toStringWithIndent(String indent) {
-            return indent + "AggregatedStats{\n" +
-                    indent + "  key='" + key + "',\n" +
-                    indent + "  numPostedByApp=" + numPostedByApp + ",\n" +
-                    indent + "  numUpdatedByApp=" + numUpdatedByApp + ",\n" +
-                    indent + "  numRemovedByApp=" + numRemovedByApp + ",\n" +
-                    indent + "  numPeopleCacheHit=" + numPeopleCacheHit + ",\n" +
-                    indent + "  numWithStaredPeople=" + numWithStaredPeople + ",\n" +
-                    indent + "  numWithValidPeople=" + numWithValidPeople + ",\n" +
-                    indent + "  numPeopleCacheMiss=" + numPeopleCacheMiss + ",\n" +
-                    indent + "  numBlocked=" + numBlocked + ",\n" +
-                    indent + "}";
+            StringBuilder output = new StringBuilder();
+            output.append(indent).append("AggregatedStats{\n");
+            String indentPlusTwo = indent + "  ";
+            output.append(indentPlusTwo);
+            output.append("key='").append(key).append("',\n");
+            output.append(indentPlusTwo);
+            output.append("numPostedByApp=").append(numPostedByApp).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numUpdatedByApp=").append(numUpdatedByApp).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numRemovedByApp=").append(numRemovedByApp).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numPeopleCacheHit=").append(numPeopleCacheHit).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numWithStaredPeople=").append(numWithStaredPeople).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numWithValidPeople=").append(numWithValidPeople).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numPeopleCacheMiss=").append(numPeopleCacheMiss).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numBlocked=").append(numBlocked).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numSuspendedByAdmin=").append(numSuspendedByAdmin).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numWithActions=").append(numWithActions).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numPrivate=").append(numPrivate).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numSecret=").append(numSecret).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numInterrupt=").append(numInterrupt).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numWithBigText=").append(numWithBigText).append(",\n");
+            output.append(indentPlusTwo);
+            output.append("numWithBigPicture=").append(numWithBigPicture).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numForegroundService=").append(numForegroundService).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numOngoing=").append(numOngoing).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numAutoCancel=").append(numAutoCancel).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numWithLargeIcon=").append(numWithLargeIcon).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numWithInbox=").append(numWithInbox).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numWithMediaSession=").append(numWithMediaSession).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numWithTitle=").append(numWithTitle).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numWithText=").append(numWithText).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numWithSubText=").append(numWithSubText).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numWithInfoText=").append(numWithInfoText).append("\n");
+            output.append(indentPlusTwo).append(noisyImportance.toString()).append("\n");
+            output.append(indentPlusTwo).append(quietImportance.toString()).append("\n");
+            output.append(indentPlusTwo).append(finalImportance.toString()).append("\n");
+            output.append(indent).append("}");
+            return output.toString();
         }
 
         public JSONObject dumpJson() throws JSONException {
@@ -508,13 +564,10 @@
             maybePut(dump, "numWithStaredPeople", numWithStaredPeople);
             maybePut(dump, "numWithValidPeople", numWithValidPeople);
             maybePut(dump, "numBlocked", numBlocked);
+            maybePut(dump, "numSuspendedByAdmin", numSuspendedByAdmin);
             maybePut(dump, "numWithActions", numWithActions);
             maybePut(dump, "numPrivate", numPrivate);
             maybePut(dump, "numSecret", numSecret);
-            maybePut(dump, "numPriorityMax", numPriorityMax);
-            maybePut(dump, "numPriorityHigh", numPriorityHigh);
-            maybePut(dump, "numPriorityLow", numPriorityLow);
-            maybePut(dump, "numPriorityMin", numPriorityMin);
             maybePut(dump, "numInterrupt", numInterrupt);
             maybePut(dump, "numWithBigText", numWithBigText);
             maybePut(dump, "numWithBigPicture", numWithBigPicture);
@@ -528,6 +581,10 @@
             maybePut(dump, "numWithText", numWithText);
             maybePut(dump, "numWithSubText", numWithSubText);
             maybePut(dump, "numWithInfoText", numWithInfoText);
+            noisyImportance.maybePut(dump, mPrevious.noisyImportance);
+            quietImportance.maybePut(dump, mPrevious.quietImportance);
+            finalImportance.maybePut(dump, mPrevious.finalImportance);
+
             return dump;
         }
 
@@ -538,6 +595,65 @@
         }
     }
 
+    private static class ImportanceHistogram {
+        // TODO define these somewhere else
+        private static final int NUM_IMPORTANCES = 5;
+        private static final String[] IMPORTANCE_NAMES = {"none", "low", "default", "high", "max"};
+        private final Context mContext;
+        private final String[] mCounterNames;
+        private final String mPrefix;
+        private int[] mCount;
+
+        ImportanceHistogram(Context context, String prefix) {
+            mContext = context;
+            mCount = new int[NUM_IMPORTANCES];
+            mCounterNames = new String[NUM_IMPORTANCES];
+            mPrefix = prefix;
+            for (int i = 0; i < NUM_IMPORTANCES; i++) {
+                mCounterNames[i] = mPrefix + IMPORTANCE_NAMES[i];
+            }
+        }
+
+        void increment(int imp) {
+            imp = imp < 0 ? 0 : imp > NUM_IMPORTANCES ? NUM_IMPORTANCES : imp;
+            mCount[imp] ++;
+        }
+
+        void maybeCount(ImportanceHistogram prev) {
+            for (int i = 0; i < NUM_IMPORTANCES; i++) {
+                final int value = mCount[i] - prev.mCount[i];
+                if (value > 0) {
+                    MetricsLogger.count(mContext, mCounterNames[i], value);
+                }
+            }
+        }
+
+        void update(ImportanceHistogram that) {
+            for (int i = 0; i < NUM_IMPORTANCES; i++) {
+                mCount[i] = that.mCount[i];
+            }
+        }
+
+        public void maybePut(JSONObject dump, ImportanceHistogram prev)
+                throws JSONException {
+            dump.put(mPrefix, new JSONArray(mCount));
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder output = new StringBuilder();
+            output.append(mPrefix).append(": [");
+            for (int i = 0; i < NUM_IMPORTANCES; i++) {
+                output.append(mCount[i]);
+                if (i < (NUM_IMPORTANCES-1)) {
+                    output.append(", ");
+                }
+            }
+            output.append("]");
+            return output.toString();
+        }
+    }
+
     /**
      * Tracks usage of an individual notification that is currently active.
      */
@@ -575,6 +691,12 @@
         public long airtimeExpandedMs = 0;
         /** Number of times the notification has been expanded by the user. */
         public long userExpansionCount = 0;
+        /** Importance directly requested by the app. */
+        public int requestedImportance;
+        /** Did the app include sound or vibration on the notificaiton. */
+        public boolean isNoisy;
+        /** Importance after initial filtering for noise and other features */
+        public int naturalImportance;
 
         public long getCurrentPosttimeMs() {
             if (posttimeElapsedMs < 0) {
@@ -686,17 +808,40 @@
 
         @Override
         public String toString() {
-            return "SingleNotificationStats{" +
-                    "posttimeElapsedMs=" + posttimeElapsedMs +
-                    ", posttimeToFirstClickMs=" + posttimeToFirstClickMs +
-                    ", posttimeToDismissMs=" + posttimeToDismissMs +
-                    ", airtimeCount=" + airtimeCount +
-                    ", airtimeMs=" + airtimeMs +
-                    ", currentAirtimeStartElapsedMs=" + currentAirtimeStartElapsedMs +
-                    ", airtimeExpandedMs=" + airtimeExpandedMs +
-                    ", posttimeToFirstVisibleExpansionMs=" + posttimeToFirstVisibleExpansionMs +
-                    ", currentAirtimeExpandedSEMs=" + currentAirtimeExpandedStartElapsedMs +
-                    '}';
+            StringBuilder output = new StringBuilder();
+            output.append("SingleNotificationStats{");
+
+            output.append("posttimeElapsedMs=").append(posttimeElapsedMs).append(", ");
+            output.append("posttimeToFirstClickMs=").append(posttimeToFirstClickMs).append(", ");
+            output.append("posttimeToDismissMs=").append(posttimeToDismissMs).append(", ");
+            output.append("airtimeCount=").append(airtimeCount).append(", ");
+            output.append("airtimeMs=").append(airtimeMs).append(", ");
+            output.append("currentAirtimeStartElapsedMs=").append(currentAirtimeStartElapsedMs)
+                    .append(", ");
+            output.append("airtimeExpandedMs=").append(airtimeExpandedMs).append(", ");
+            output.append("posttimeToFirstVisibleExpansionMs=")
+                    .append(posttimeToFirstVisibleExpansionMs).append(", ");
+            output.append("currentAirtimeExpandedStartElapsedMs=")
+                    .append(currentAirtimeExpandedStartElapsedMs).append(", ");
+            output.append("requestedImportance=").append(requestedImportance).append(", ");
+            output.append("naturalImportance=").append(naturalImportance).append(", ");
+            output.append("isNoisy=").append(isNoisy);
+            output.append('}');
+            return output.toString();
+        }
+
+        /** Copy useful information out of the stats from the pre-update notifications. */
+        public void updateFrom(SingleNotificationStats old) {
+            posttimeElapsedMs = old.posttimeElapsedMs;
+            posttimeToFirstClickMs = old.posttimeToFirstClickMs;
+            airtimeCount = old.airtimeCount;
+            posttimeToFirstAirtimeMs = old.posttimeToFirstAirtimeMs;
+            currentAirtimeStartElapsedMs = old.currentAirtimeStartElapsedMs;
+            airtimeMs = old.airtimeMs;
+            posttimeToFirstVisibleExpansionMs = old.posttimeToFirstVisibleExpansionMs;
+            currentAirtimeExpandedStartElapsedMs = old.currentAirtimeExpandedStartElapsedMs;
+            airtimeExpandedMs = old.airtimeExpandedMs;
+            userExpansionCount = old.userExpansionCount;
         }
     }
 
@@ -741,7 +886,7 @@
         private static final int MSG_DISMISS = 4;
 
         private static final String DB_NAME = "notification_log.db";
-        private static final int DB_VERSION = 4;
+        private static final int DB_VERSION = 5;
 
         /** Age in ms after which events are pruned from the DB. */
         private static final long HORIZON_MS = 7 * 24 * 60 * 60 * 1000L;  // 1 week
@@ -762,7 +907,11 @@
         private static final String COL_WHEN_MS = "when_ms";
         private static final String COL_DEFAULTS = "defaults";
         private static final String COL_FLAGS = "flags";
-        private static final String COL_PRIORITY = "priority";
+        private static final String COL_IMPORTANCE_REQ = "importance_request";
+        private static final String COL_IMPORTANCE_FINAL = "importance_final";
+        private static final String COL_NOISY = "noisy";
+        private static final String COL_MUTED = "muted";
+        private static final String COL_DEMOTED = "demoted";
         private static final String COL_CATEGORY = "category";
         private static final String COL_ACTION_COUNT = "action_count";
         private static final String COL_POSTTIME_MS = "posttime_ms";
@@ -776,14 +925,28 @@
         private static final int EVENT_TYPE_CLICK = 2;
         private static final int EVENT_TYPE_REMOVE = 3;
         private static final int EVENT_TYPE_DISMISS = 4;
-
         private static long sLastPruneMs;
+
         private static long sNumWrites;
-
         private final SQLiteOpenHelper mHelper;
-        private final Handler mWriteHandler;
 
+        private final Handler mWriteHandler;
         private static final long DAY_MS = 24 * 60 * 60 * 1000;
+        private static final String STATS_QUERY = "SELECT " +
+                COL_EVENT_USER_ID + ", " +
+                COL_PKG + ", " +
+                // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)'
+                "CAST(((%d - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " +
+                "AS day, " +
+                "COUNT(*) AS cnt, " +
+                "SUM(" + COL_MUTED + ") as muted, " +
+                "SUM(" + COL_NOISY + ") as noisy, " +
+                "SUM(" + COL_DEMOTED + ") as demoted " +
+                "FROM " + TAB_LOG + " " +
+                "WHERE " +
+                COL_EVENT_TYPE + "=" + EVENT_TYPE_POST +
+                " AND " + COL_EVENT_TIME + " > %d " +
+                " GROUP BY " + COL_EVENT_USER_ID + ", day, " + COL_PKG;
 
         public SQLiteLog(Context context) {
             HandlerThread backgroundThread = new HandlerThread("notification-sqlite-log",
@@ -828,7 +991,11 @@
                             COL_WHEN_MS + " INT," +
                             COL_DEFAULTS + " INT," +
                             COL_FLAGS + " INT," +
-                            COL_PRIORITY + " INT," +
+                            COL_IMPORTANCE_REQ + " INT," +
+                            COL_IMPORTANCE_FINAL + " INT," +
+                            COL_NOISY + " INT," +
+                            COL_MUTED + " INT," +
+                            COL_DEMOTED + " INT," +
                             COL_CATEGORY + " TEXT," +
                             COL_ACTION_COUNT + " INT," +
                             COL_POSTTIME_MS + " INT," +
@@ -841,8 +1008,7 @@
 
                 @Override
                 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-                    if (oldVersion <= 3) {
-                        // Version 3 creation left 'log' in a weird state. Just reset for now.
+                    if (oldVersion != newVersion) {
                         db.execSQL("DROP TABLE IF EXISTS " + TAB_LOG);
                         onCreate(db);
                     }
@@ -866,22 +1032,11 @@
             mWriteHandler.sendMessage(mWriteHandler.obtainMessage(MSG_DISMISS, notification));
         }
 
-        private JSONArray JsonPostFrequencies(DumpFilter filter) throws JSONException {
+        private JSONArray jsonPostFrequencies(DumpFilter filter) throws JSONException {
             JSONArray frequencies = new JSONArray();
             SQLiteDatabase db = mHelper.getReadableDatabase();
             long midnight = getMidnightMs();
-            String q = "SELECT " +
-                    COL_EVENT_USER_ID + ", " +
-                    COL_PKG + ", " +
-                    // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)'
-                    "CAST(((" + midnight + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " +
-                    "AS day, " +
-                    "COUNT(*) AS cnt " +
-                    "FROM " + TAB_LOG + " " +
-                    "WHERE " +
-                    COL_EVENT_TYPE + "=" + EVENT_TYPE_POST +
-                    " AND " + COL_EVENT_TIME + " > " + filter.since +
-                    " GROUP BY " + COL_EVENT_USER_ID + ", day, " + COL_PKG;
+            String q = String.format(STATS_QUERY, midnight, filter.since);
             Cursor cursor = db.rawQuery(q, null);
             try {
                 for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
@@ -890,11 +1045,17 @@
                     if (filter != null && !filter.matches(pkg)) continue;
                     int day = cursor.getInt(2);
                     int count = cursor.getInt(3);
+                    int muted = cursor.getInt(4);
+                    int noisy = cursor.getInt(5);
+                    int demoted = cursor.getInt(6);
                     JSONObject row = new JSONObject();
                     row.put("user_id", userId);
                     row.put("package", pkg);
                     row.put("day", day);
                     row.put("count", count);
+                    row.put("noisy", noisy);
+                    row.put("muted", muted);
+                    row.put("demoted", demoted);
                     frequencies.put(row);
                 }
             } finally {
@@ -906,17 +1067,7 @@
         public void printPostFrequencies(PrintWriter pw, String indent, DumpFilter filter) {
             SQLiteDatabase db = mHelper.getReadableDatabase();
             long midnight = getMidnightMs();
-            String q = "SELECT " +
-                    COL_EVENT_USER_ID + ", " +
-                    COL_PKG + ", " +
-                    // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)'
-                    "CAST(((" + midnight + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " +
-                        "AS day, " +
-                    "COUNT(*) AS cnt " +
-                    "FROM " + TAB_LOG + " " +
-                    "WHERE " +
-                    COL_EVENT_TYPE + "=" + EVENT_TYPE_POST + " " +
-                    "GROUP BY " + COL_EVENT_USER_ID + ", day, " + COL_PKG;
+            String q = String.format(STATS_QUERY, midnight, filter.since);
             Cursor cursor = db.rawQuery(q, null);
             try {
                 for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
@@ -925,8 +1076,12 @@
                     if (filter != null && !filter.matches(pkg)) continue;
                     int day = cursor.getInt(2);
                     int count = cursor.getInt(3);
+                    int muted = cursor.getInt(4);
+                    int noisy = cursor.getInt(5);
+                    int demoted = cursor.getInt(6);
                     pw.println(indent + "post_frequency{user_id=" + userId + ",pkg=" + pkg +
-                            ",day=" + day + ",count=" + count + "}");
+                            ",day=" + day + ",count=" + count + ",muted=" + muted + "/" + noisy +
+                            ",demoted=" + demoted + "}");
                 }
             } finally {
                 cursor.close();
@@ -985,7 +1140,18 @@
             }
             outCv.put(COL_WHEN_MS, r.sbn.getPostTime());
             outCv.put(COL_FLAGS, r.getNotification().flags);
-            outCv.put(COL_PRIORITY, r.getNotification().priority);
+            final int before = r.stats.requestedImportance;
+            final int after = r.getImportance();
+            final boolean noisy = r.stats.isNoisy;
+            outCv.put(COL_IMPORTANCE_REQ, before);
+            outCv.put(COL_IMPORTANCE_FINAL, after);
+            outCv.put(COL_DEMOTED, after < before ? 1 : 0);
+            outCv.put(COL_NOISY, noisy);
+            if (noisy && after < IMPORTANCE_HIGH) {
+                outCv.put(COL_MUTED, 1);
+            } else {
+                outCv.put(COL_MUTED, 0);
+            }
             if (r.getNotification().category != null) {
                 outCv.put(COL_CATEGORY, r.getNotification().category);
             }
@@ -1008,7 +1174,9 @@
         public JSONObject dumpJson(DumpFilter filter) {
             JSONObject dump = new JSONObject();
             try {
-                dump.put("post_frequency", JsonPostFrequencies(filter));
+                dump.put("post_frequency", jsonPostFrequencies(filter));
+                dump.put("since", filter.since);
+                dump.put("now", System.currentTimeMillis());
             } catch (JSONException e) {
                 // pass
             }
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 9b10ef2..7f85e1f 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -23,20 +23,18 @@
 
     List<Notification.Topic> getTopics(String packageName, int uid);
 
-    int getTopicPriority(String packageName, int uid, Notification.Topic topic);
+    int getPriority(String packageName, int uid, Notification.Topic topic);
 
-    void setTopicPriority(String packageName, int uid, Notification.Topic topic, int priority);
+    void setPriority(String packageName, int uid, Notification.Topic topic, int priority);
 
-    int getTopicVisibilityOverride(String packageName, int uid, Notification.Topic topic);
+    int getVisibilityOverride(String packageName, int uid, Notification.Topic topic);
 
-    void setTopicVisibilityOverride(String packageName, int uid, Notification.Topic topic,
+    void setVisibilityOverride(String packageName, int uid, Notification.Topic topic,
             int visibility);
 
-    void setTopicImportance(String packageName, int uid, Notification.Topic topic, int importance);
+    void setImportance(String packageName, int uid, Notification.Topic topic, int importance);
 
-    int getTopicImportance(String packageName, int uid, Notification.Topic topic);
-
-    void setAppImportance(String packageName, int uid, int importance);
+    int getImportance(String packageName, int uid, Notification.Topic topic);
 
     boolean doesAppUseTopics(String packageName, int uid);
 }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index ce4ecd3..827482f 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -164,6 +164,8 @@
                             r = getOrCreateRecord(name, uid);
                         }
                         r.importance = safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
+                        r.priority = priority;
+                        r.visibility = vis;
 
                         // Migrate package level settings to the default topic.
                         // Might be overwritten by parseTopics.
@@ -245,7 +247,15 @@
             }
             out.startTag(null, TAG_PACKAGE);
             out.attribute(null, ATT_NAME, r.pkg);
-            out.attribute(null, ATT_IMPORTANCE, Integer.toString(r.importance));
+            if (r.importance != DEFAULT_IMPORTANCE) {
+                out.attribute(null, ATT_IMPORTANCE, Integer.toString(r.importance));
+            }
+            if (r.priority != DEFAULT_PRIORITY) {
+                out.attribute(null, ATT_PRIORITY, Integer.toString(r.priority));
+            }
+            if (r.visibility != DEFAULT_VISIBILITY) {
+                out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
+            }
 
             if (!forBackup) {
                 out.attribute(null, ATT_UID, Integer.toString(r.uid));
@@ -373,66 +383,109 @@
     public List<Notification.Topic> getTopics(String packageName, int uid) {
         final Record r = getOrCreateRecord(packageName, uid);
         List<Notification.Topic> topics = new ArrayList<>();
-        for (Topic t :  r.topics.values()) {
+        for (Topic t : r.topics.values()) {
             topics.add(t.topic);
         }
         return topics;
     }
 
+    /**
+     * Gets priority. If a topic is given, returns the priority of that topic. Otherwise, the
+     * priority of the app.
+     */
     @Override
-    public int getTopicPriority(String packageName, int uid, Notification.Topic topic) {
+    public int getPriority(String packageName, int uid, Notification.Topic topic) {
         final Record r = getOrCreateRecord(packageName, uid);
+        if (topic == null) {
+            return r.priority;
+        }
         return getOrCreateTopic(r, topic).priority;
     }
 
+    /**
+     * Sets priority. If a topic is given, sets the priority of that topic. If not,
+     * sets the default priority for all new topics that appear in the future, and resets
+     * the priority of all current topics.
+     */
     @Override
-    public void setTopicPriority(String packageName, int uid, Notification.Topic topic,
+    public void setPriority(String packageName, int uid, Notification.Topic topic,
             int priority) {
         final Record r = getOrCreateRecord(packageName, uid);
-        getOrCreateTopic(r, topic).priority = priority;
-        updateConfig();
-    }
-
-    @Override
-    public int getTopicVisibilityOverride(String packageName, int uid, Notification.Topic topic) {
-        final Record r = getOrCreateRecord(packageName, uid);
-        return getOrCreateTopic(r, topic).visibility;
-    }
-
-    @Override
-    public void setTopicVisibilityOverride(String pkgName, int uid, Notification.Topic topic,
-        int visibility) {
-        final Record r = getOrCreateRecord(pkgName, uid);
-        getOrCreateTopic(r, topic).visibility = visibility;
-        updateConfig();
-    }
-
-    @Override
-    public int getTopicImportance(String packageName, int uid, Notification.Topic topic) {
-        final Record r = getOrCreateRecord(packageName, uid);
-        return getOrCreateTopic(r, topic).importance;
-    }
-
-    @Override
-    public void setTopicImportance(String pkgName, int uid, Notification.Topic topic,
-            int importance) {
-        final Record r = getOrCreateRecord(pkgName, uid);
-        getOrCreateTopic(r, topic).importance = importance;
+        if (topic == null) {
+            r.priority = priority;
+            for (Topic t : r.topics.values()) {
+                t.priority = priority;
+            }
+        } else {
+            getOrCreateTopic(r, topic).priority = priority;
+        }
         updateConfig();
     }
 
     /**
-     * Sets the default importance for all new topics that appear in the future, and resets
+     * Gets visual override. If a topic is given, returns the override of that topic. Otherwise, the
+     * override of the app.
+     */
+    @Override
+    public int getVisibilityOverride(String packageName, int uid, Notification.Topic topic) {
+        final Record r = getOrCreateRecord(packageName, uid);
+        if (topic == null) {
+            return r.visibility;
+        }
+        return getOrCreateTopic(r, topic).visibility;
+    }
+
+    /**
+     * Sets visibility override. If a topic is given, sets the override of that topic. If not,
+     * sets the default override for all new topics that appear in the future, and resets
+     * the override of all current topics.
+     */
+    @Override
+    public void setVisibilityOverride(String pkgName, int uid, Notification.Topic topic,
+        int visibility) {
+        final Record r = getOrCreateRecord(pkgName, uid);
+        if (topic == null) {
+            r.visibility = visibility;
+            for (Topic t : r.topics.values()) {
+                t.visibility = visibility;
+            }
+        } else {
+            getOrCreateTopic(r, topic).visibility = visibility;
+        }
+        updateConfig();
+    }
+
+    /**
+     * Gets importance. If a topic is given, returns the importance of that topic. Otherwise, the
+     * importance of the app.
+     */
+    @Override
+    public int getImportance(String packageName, int uid, Notification.Topic topic) {
+        final Record r = getOrCreateRecord(packageName, uid);
+        if (topic == null) {
+            return r.importance;
+        }
+        return getOrCreateTopic(r, topic).importance;
+    }
+
+    /**
+     * Sets importance. If a topic is given, sets the importance of that topic. If not, sets the
+     * default importance for all new topics that appear in the future, and resets
      * the importance of all current topics (unless the app is being blocked).
      */
     @Override
-    public void setAppImportance(String pkgName, int uid, int importance) {
+    public void setImportance(String pkgName, int uid, Notification.Topic topic,
+            int importance) {
         final Record r = getOrCreateRecord(pkgName, uid);
-        r.importance = importance;
-        if (Ranking.IMPORTANCE_NONE != importance) {
-            for (Topic t : r.topics.values()) {
-                t.importance = importance;
+        if (topic == null) {
+            r.importance = importance;
+            if (Ranking.IMPORTANCE_NONE != importance) {
+                for (Topic t : r.topics.values()) {
+                    t.importance = importance;
+                }
             }
+        } else {
+            getOrCreateTopic(r, topic).importance = importance;
         }
         updateConfig();
     }
@@ -459,6 +512,8 @@
         } else {
             t = new Topic(topic);
             t.importance = r.importance;
+            t.priority = r.priority;
+            t.visibility = r.visibility;
             r.topics.put(topic.getId(), t);
             return t;
         }
@@ -503,8 +558,18 @@
                 pw.print(" (");
                 pw.print(r.uid == Record.UNKNOWN_UID ? "UNKNOWN_UID" : Integer.toString(r.uid));
                 pw.print(')');
-                pw.print(" importance=");
-                pw.print(Ranking.importanceToString(r.importance));
+                if (r.importance != DEFAULT_IMPORTANCE) {
+                    pw.print(" importance=");
+                    pw.print(Ranking.importanceToString(r.importance));
+                }
+                if (r.priority != DEFAULT_PRIORITY) {
+                    pw.print(" priority=");
+                    pw.print(Ranking.importanceToString(r.priority));
+                }
+                if (r.visibility != DEFAULT_VISIBILITY) {
+                    pw.print(" visibility=");
+                    pw.print(Ranking.importanceToString(r.visibility));
+                }
                 pw.println();
                 for (Topic t : r.topics.values()) {
                     pw.print(prefix);
@@ -561,6 +626,8 @@
         String pkg;
         int uid = UNKNOWN_UID;
         int importance = DEFAULT_IMPORTANCE;
+        int priority = DEFAULT_PRIORITY;
+        int visibility = DEFAULT_VISIBILITY;
         Map<String, Topic> topics = new ArrayMap<>();
    }
 
diff --git a/services/core/java/com/android/server/notification/TopicImportanceExtractor.java b/services/core/java/com/android/server/notification/TopicImportanceExtractor.java
index 01770d0..c6b3e0f 100644
--- a/services/core/java/com/android/server/notification/TopicImportanceExtractor.java
+++ b/services/core/java/com/android/server/notification/TopicImportanceExtractor.java
@@ -42,7 +42,7 @@
             return null;
         }
 
-        final int topicImportance = mConfig.getTopicImportance(record.sbn.getPackageName(),
+        final int topicImportance = mConfig.getImportance(record.sbn.getPackageName(),
                 record.sbn.getUid(), record.sbn.getNotification().getTopic());
         record.setTopicImportance(topicImportance);
 
diff --git a/services/core/java/com/android/server/notification/TopicPriorityExtractor.java b/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
index 5bf989ae..1df5c2b 100644
--- a/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
+++ b/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
@@ -42,7 +42,7 @@
             return null;
         }
 
-        final int packagePriority = mConfig.getTopicPriority(record.sbn.getPackageName(),
+        final int packagePriority = mConfig.getPriority(record.sbn.getPackageName(),
                 record.sbn.getUid(), record.sbn.getNotification().getTopic());
         record.setPackagePriority(packagePriority);
 
diff --git a/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java b/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
index e053382..eaa3ed3 100644
--- a/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
+++ b/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
@@ -42,7 +42,7 @@
             return null;
         }
 
-        final int packageVisibility = mConfig.getTopicVisibilityOverride(
+        final int packageVisibility = mConfig.getVisibilityOverride(
                 record.sbn.getPackageName(), record.sbn.getUid(),
                 record.sbn.getNotification().getTopic());
         record.setPackageVisibilityOverride(packageVisibility);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f05e45f..d11da79 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3517,7 +3517,7 @@
     /**
      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
-     * @param checkShell TODO(yamasani):
+     * @param checkShell whether to prevent shell from access if there's a debugging restriction
      * @param message the message to log on security exception
      */
     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 5b9f0b3..0f614ca 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -25,9 +25,11 @@
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.IStopUserCallback;
+import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -302,6 +304,12 @@
 
     private final LockPatternUtils mLockPatternUtils;
 
+    /**
+     * Whether all users should be created ephemeral.
+     */
+    @GuardedBy("mUsersLock")
+    private boolean mForceEphemeralUsers;
+
     private static UserManagerService sInstance;
 
     public static UserManagerService getInstance() {
@@ -552,22 +560,13 @@
     }
 
     private void broadcastProfileAvailabilityChanges(UserHandle profileHandle,
-            UserHandle parentHandle, Bundle extras) {
-        // Send intent to profile
-        Intent intent = new Intent(Intent.ACTION_AVAILABILITY_CHANGED);
+            UserHandle parentHandle, boolean inQuietMode) {
+        Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
+        intent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode);
+        intent.putExtra(Intent.EXTRA_USER, profileHandle);
+        intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-        intent.putExtras(extras);
-        mContext.sendBroadcastAsUser(intent, profileHandle);
-
-        // Send intent to parent
-        if (parentHandle != null) {
-            intent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
-            intent.putExtra(Intent.EXTRA_USER, profileHandle);
-            intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            intent.putExtras(extras);
-            mContext.sendBroadcastAsUser(intent, parentHandle);
-        }
+        mContext.sendBroadcastAsUser(intent, parentHandle);
     }
 
     @Override
@@ -591,10 +590,21 @@
             }
         }
         if (changed) {
-            Bundle extras = new Bundle();
-            extras.putBoolean(Intent.EXTRA_QUIET_MODE, enableQuietMode);
-            broadcastProfileAvailabilityChanges(profile.getUserHandle(),
-                    parent != null ? parent.getUserHandle() : null, extras);
+            long identity = Binder.clearCallingIdentity();
+            try {
+                if (enableQuietMode) {
+                    ActivityManagerNative.getDefault().stopUser(userHandle, /* force */true, null);
+                } else {
+                    ActivityManagerNative.getDefault().startUserInBackground(userHandle);
+                }
+            } catch (RemoteException e) {
+                Slog.e(LOG_TAG, "fail to start/stop user for quiet mode", e);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+
+            broadcastProfileAvailabilityChanges(profile.getUserHandle(), parent.getUserHandle(),
+                    enableQuietMode);
         }
     }
 
@@ -606,7 +616,7 @@
                 info = getUserInfoLU(userHandle);
             }
             if (info == null || !info.isManagedProfile()) {
-                throw new IllegalArgumentException("User " + userHandle + " is not a profile");
+                return false;
             }
             return info.isQuietModeEnabled();
         }
@@ -1834,23 +1844,25 @@
                     }
                 }
 
-                // Add ephemeral flag to guests if required. Also inherit it from parent.
+                userId = getNextAvailableId();
+                Environment.getUserSystemDirectory(userId).mkdirs();
                 boolean ephemeralGuests = Resources.getSystem()
                         .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
-                if ((isGuest && ephemeralGuests)
-                        || (parent != null && parent.info.isEphemeral())) {
-                    flags |= UserInfo.FLAG_EPHEMERAL;
-                }
-                userId = getNextAvailableId();
-                userInfo = new UserInfo(userId, name, null, flags);
-                userInfo.serialNumber = mNextSerialNumber++;
-                long now = System.currentTimeMillis();
-                userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
-                userInfo.partial = true;
-                userData = new UserData();
-                userData.info = userInfo;
-                Environment.getUserSystemDirectory(userInfo.id).mkdirs();
+
                 synchronized (mUsersLock) {
+                    // Add ephemeral flag to guests/users if required. Also inherit it from parent.
+                    if ((isGuest && ephemeralGuests) || mForceEphemeralUsers
+                            || (parent != null && parent.info.isEphemeral())) {
+                        flags |= UserInfo.FLAG_EPHEMERAL;
+                    }
+
+                    userInfo = new UserInfo(userId, name, null, flags);
+                    userInfo.serialNumber = mNextSerialNumber++;
+                    long now = System.currentTimeMillis();
+                    userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
+                    userInfo.partial = true;
+                    userData = new UserData();
+                    userData.info = userInfo;
                     mUsers.put(userId, userData);
                 }
                 writeUserListLP();
@@ -2912,6 +2924,61 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
+
+        @Override
+        public void setForceEphemeralUsers(boolean forceEphemeralUsers) {
+            synchronized (mUsersLock) {
+                mForceEphemeralUsers = forceEphemeralUsers;
+            }
+        }
+
+        @Override
+        public void removeAllUsers() {
+            if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) {
+                // Remove the non-system users straight away.
+                removeNonSystemUsers();
+            } else {
+                // Switch to the system user first and then remove the other users.
+                BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        int userId =
+                                intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+                        if (userId != UserHandle.USER_SYSTEM) {
+                            return;
+                        }
+                        mContext.unregisterReceiver(this);
+                        removeNonSystemUsers();
+                    }
+                };
+                IntentFilter userSwitchedFilter = new IntentFilter();
+                userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED);
+                mContext.registerReceiver(
+                        userSwitchedReceiver, userSwitchedFilter, null, mHandler);
+
+                // Switch to the system user.
+                ActivityManager am =
+                        (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+                am.switchUser(UserHandle.USER_SYSTEM);
+            }
+        }
+    }
+
+    /* Remove all the users except of the system one. */
+    private void removeNonSystemUsers() {
+        ArrayList<UserInfo> usersToRemove = new ArrayList<>();
+        synchronized (mUsersLock) {
+            final int userSize = mUsers.size();
+            for (int i = 0; i < userSize; i++) {
+                UserInfo ui = mUsers.valueAt(i).info;
+                if (ui.id != UserHandle.USER_SYSTEM) {
+                    usersToRemove.add(ui);
+                }
+            }
+        }
+        for (UserInfo ui: usersToRemove) {
+            removeUser(ui.id);
+        }
     }
 
     private class Shell extends ShellCommand {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 290019c..a1f24f7 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -131,6 +131,7 @@
     private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
     private static final int WAKE_LOCK_DOZE = 1 << 6;
     private static final int WAKE_LOCK_DRAW = 1 << 7;
+    private static final int WAKE_LOCK_SUSTAINED_PERFORMANCE = 1 << 8;
 
     // Summarizes the user activity state.
     private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
@@ -149,6 +150,7 @@
 
     // Power hints defined in hardware/libhardware/include/hardware/power.h.
     private static final int POWER_HINT_LOW_POWER = 5;
+    private static final int POWER_HINT_SUSTAINED_PERFORMANCE = 6;
 
     // Power features defined in hardware/libhardware/include/hardware/power.h.
     private static final int POWER_FEATURE_DOUBLE_TAP_TO_WAKE = 1;
@@ -444,6 +446,9 @@
     // True if we are currently in light device idle mode.
     private boolean mLightDeviceIdleMode;
 
+    // True if we are currently in sustained performance mode.
+    private boolean mSustainedPerformanceMode;
+
     // Set of app ids that we will always respect the wake locks for.
     int[] mDeviceIdleWhitelist = new int[0];
 
@@ -452,6 +457,8 @@
 
     private final SparseIntArray mUidState = new SparseIntArray();
 
+    private final SparseIntArray mSustainedPerformanceUid = new SparseIntArray();
+
     // True if theater mode is enabled
     private boolean mTheaterModeEnabled;
 
@@ -811,6 +818,12 @@
                     throw new IllegalArgumentException("Wake lock is already dead.");
                 }
                 mWakeLocks.add(wakeLock);
+
+                if ((flags & PowerManager.WAKE_LOCK_LEVEL_MASK)
+                        == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK) {
+                    int numberWakelock = mSustainedPerformanceUid.get(uid);
+                    mSustainedPerformanceUid.put(uid, numberWakelock + 1);
+                }
                 setWakeLockDisabledStateLocked(wakeLock);
                 notifyAcquire = true;
             }
@@ -879,6 +892,17 @@
                 mRequestWaitForNegativeProximity = true;
             }
 
+
+            if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
+                    == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK) {
+                int numberWakelock = mSustainedPerformanceUid.get(wakeLock.mOwnerUid);
+                if (numberWakelock == 1) {
+                    mSustainedPerformanceUid.delete(wakeLock.mOwnerUid);
+                } else {
+                    mSustainedPerformanceUid.put(wakeLock.mOwnerUid, numberWakelock - 1);
+                }
+            }
+
             wakeLock.mLock.unlinkToDeath(wakeLock, 0);
             removeWakeLockLocked(wakeLock, index);
         }
@@ -1501,6 +1525,10 @@
                         break;
                     case PowerManager.DRAW_WAKE_LOCK:
                         mWakeLockSummary |= WAKE_LOCK_DRAW;
+                    case PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK:
+                        if (!wakeLock.mDisabled) {
+                            mWakeLockSummary |= WAKE_LOCK_SUSTAINED_PERFORMANCE;
+                        }
                         break;
                 }
             }
@@ -2198,6 +2226,14 @@
         if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
             setHalAutoSuspendModeLocked(true);
         }
+
+        if (mSustainedPerformanceMode
+                && (mWakeLockSummary & WAKE_LOCK_SUSTAINED_PERFORMANCE) == 0) {
+            setSustainedPerformanceModeLocked(false);
+        } else if (!mSustainedPerformanceMode
+                && (mWakeLockSummary & WAKE_LOCK_SUSTAINED_PERFORMANCE) != 0) {
+            setSustainedPerformanceModeLocked(true);
+        }
     }
 
     /**
@@ -2296,6 +2332,12 @@
         }
     }
 
+    private void setSustainedPerformanceModeLocked(boolean mode) {
+            mSustainedPerformanceMode = mode;
+            powerHintInternal(POWER_HINT_SUSTAINED_PERFORMANCE,
+                              mSustainedPerformanceMode ? 1 : 0);
+    }
+
     boolean isDeviceIdleModeInternal() {
         synchronized (mLock) {
             return mDeviceIdleMode;
@@ -2425,7 +2467,7 @@
     void updateUidProcStateInternal(int uid, int procState) {
         synchronized (mLock) {
             mUidState.put(uid, procState);
-            if (mDeviceIdleMode) {
+            if (mDeviceIdleMode || mSustainedPerformanceUid.get(uid) != 0) {
                 updateWakeLockDisabledStatesLocked();
             }
         }
@@ -2446,7 +2488,9 @@
         for (int i = 0; i < numWakeLocks; i++) {
             final WakeLock wakeLock = mWakeLocks.get(i);
             if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
-                    == PowerManager.PARTIAL_WAKE_LOCK) {
+                    == PowerManager.PARTIAL_WAKE_LOCK
+                    || (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
+                    == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK) {
                 if (setWakeLockDisabledStateLocked(wakeLock)) {
                     changed = true;
                     if (wakeLock.mDisabled) {
@@ -2465,9 +2509,9 @@
     }
 
     private boolean setWakeLockDisabledStateLocked(WakeLock wakeLock) {
+        boolean disabled = false;
         if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
                 == PowerManager.PARTIAL_WAKE_LOCK) {
-            boolean disabled = false;
             if (mDeviceIdleMode) {
                 final int appid = UserHandle.getAppId(wakeLock.mOwnerUid);
                 // If we are in idle mode, we will ignore all partial wake locks that are
@@ -2481,10 +2525,16 @@
                     disabled = true;
                 }
             }
-            if (wakeLock.mDisabled != disabled) {
-                wakeLock.mDisabled = disabled;
-                return true;
-            }
+        } else if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
+                == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK
+                && mUidState.get(wakeLock.mOwnerUid,
+                                 ActivityManager.PROCESS_STATE_CACHED_EMPTY)
+                > ActivityManager.PROCESS_STATE_TOP) {
+            disabled = true;
+        }
+        if (wakeLock.mDisabled != disabled) {
+            wakeLock.mDisabled = disabled;
+            return true;
         }
         return false;
     }
@@ -2695,6 +2745,7 @@
             pw.println("  mBatteryLevelLow=" + mBatteryLevelLow);
             pw.println("  mLightDeviceIdleMode=" + mLightDeviceIdleMode);
             pw.println("  mDeviceIdleMode=" + mDeviceIdleMode);
+            pw.println("  mSustainedPerformanceMode=" + mSustainedPerformanceMode);
             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
             pw.println("  mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
@@ -2809,6 +2860,14 @@
             pw.println();
             pw.println("Display Power: " + mDisplayPowerCallbacks);
 
+            pw.println();
+            pw.println("Sustained Performance UIDs:");
+            for (int i=0; i<mSustainedPerformanceUid.size(); i++) {
+                pw.print("  UID "); UserHandle.formatUid(pw, mSustainedPerformanceUid.keyAt(i));
+                pw.print(": "); pw.println(mSustainedPerformanceUid.valueAt(i));
+            }
+
+
             wcd = mWirelessChargerDetector;
         }
 
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 1d498e1..b54e866 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -60,7 +60,6 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
 import android.util.Xml;
 import android.view.IWindowManager;
 import android.view.WindowManagerGlobal;
@@ -103,6 +102,9 @@
     private static final int MSG_CLEANUP_USER = 8;
     private static final int MSG_SWITCH_USER = 9;
     private static final int MSG_SET_DEVICE_LOCKED = 10;
+    private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 11;
+
+    public static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
 
     private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
     private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
@@ -120,6 +122,11 @@
     @GuardedBy("mDeviceLockedForUser")
     private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
 
+    @GuardedBy("mDeviceLockedForUser")
+    private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
+
+    private final StrongAuthTracker mStrongAuthTracker;
+
     private boolean mTrustAgentsCanRun = false;
     private int mCurrentUser = UserHandle.USER_SYSTEM;
 
@@ -129,6 +136,13 @@
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
         mLockPatternUtils = new LockPatternUtils(context);
+
+        mStrongAuthTracker = new StrongAuthTracker(context) {
+            @Override
+            public void onStrongAuthRequiredChanged(int userId) {
+                refreshAgentList(userId);
+            }
+        };
     }
 
     @Override
@@ -187,7 +201,12 @@
     }
 
     public void updateTrust(int userId, int flags) {
-        dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
+        boolean managed = aggregateIsTrustManaged(userId);
+        dispatchOnTrustManagedChanged(managed, userId);
+        if (mStrongAuthTracker.isTrustAllowedForUser(userId)
+                && isTrustUsuallyManagedInternal(userId) != managed) {
+            updateTrustUsuallyManaged(userId, managed);
+        }
         boolean trusted = aggregateIsTrusted(userId);
         boolean changed;
         synchronized (mUserIsTrusted) {
@@ -200,6 +219,18 @@
         }
     }
 
+    private void updateTrustUsuallyManaged(int userId, boolean managed) {
+        synchronized (mTrustUsuallyManagedForUser) {
+            mTrustUsuallyManagedForUser.put(userId, managed);
+        }
+        // Wait a few minutes before committing to flash, in case the trust agent is transiently not
+        // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
+        mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
+        mHandler.sendMessageDelayed(
+                mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
+                TRUST_USUALLY_MANAGED_FLUSH_DELAY);
+    }
+
     void refreshAgentList(int userId) {
         if (DEBUG) Slog.d(TAG, "refreshAgentList()");
         if (!mTrustAgentsCanRun) {
@@ -787,8 +818,37 @@
             mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
                     .sendToTarget();
         }
+
+        @Override
+        public boolean isTrustUsuallyManaged(int userId) {
+            mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
+                    "query trust state");
+            return isTrustUsuallyManagedInternal(userId);
+        }
     };
 
+    private boolean isTrustUsuallyManagedInternal(int userId) {
+        synchronized (mTrustUsuallyManagedForUser) {
+            int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
+            if (i >= 0) {
+                return mTrustUsuallyManagedForUser.valueAt(i);
+            }
+        }
+        // It's not in memory yet, get the value from persisted storage instead
+        boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
+        synchronized (mTrustUsuallyManagedForUser) {
+            int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
+            if (i >= 0) {
+                // Someone set the trust usually managed in the mean time. Better use that.
+                return mTrustUsuallyManagedForUser.valueAt(i);
+            } else {
+                // .. otherwise it's safe to cache the fetched value now.
+                mTrustUsuallyManagedForUser.put(userId, persistedValue);
+                return persistedValue;
+            }
+        }
+    }
+
     private int resolveProfileParent(int userId) {
         long identity = Binder.clearCallingIdentity();
         try {
@@ -834,6 +894,19 @@
                 case MSG_SET_DEVICE_LOCKED:
                     setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
                     break;
+                case MSG_FLUSH_TRUST_USUALLY_MANAGED:
+                    SparseBooleanArray usuallyManaged;
+                    synchronized (mTrustUsuallyManagedForUser) {
+                        usuallyManaged = mTrustUsuallyManagedForUser.clone();
+                    }
+
+                    for (int i = 0; i < usuallyManaged.size(); i++) {
+                        int userId = usuallyManaged.keyAt(i);
+                        boolean value = usuallyManaged.valueAt(i);
+                        if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
+                            mLockPatternUtils.setTrustUsuallyManaged(value, userId);
+                        }
+                    }
             }
         }
     };
@@ -856,13 +929,6 @@
         }
     };
 
-    private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker() {
-        @Override
-        public void onStrongAuthRequiredChanged(int userId) {
-            refreshAgentList(userId);
-        }
-    };
-
     private class Receiver extends BroadcastReceiver {
 
         @Override
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 3193ff8..62e7fb4 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -314,7 +314,8 @@
                 }
             } else {
                 try {
-                    inputList.add(TvInputInfo.createTvInputInfo(mContext, ri));
+                    TvInputInfo info = new TvInputInfo.Builder(mContext, ri).build();
+                    inputList.add(info);
                 } catch (XmlPullParserException | IOException e) {
                     Slog.e(TAG, "failed to load TV input " + si.name, e);
                     continue;
@@ -435,7 +436,11 @@
         for (SessionState state : userState.sessionStateMap.values()) {
             if (state.session != null) {
                 try {
-                    state.session.release();
+                    if (state.isRecordingSession) {
+                        state.session.disconnect();
+                    } else {
+                        state.session.release();
+                    }
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in release", e);
                 }
@@ -604,7 +609,11 @@
 
         // Create a session. When failed, send a null token immediately.
         try {
-            service.createSession(channels[1], callback, sessionState.info.getId());
+            if (sessionState.isRecordingSession) {
+                service.createRecordingSession(callback, sessionState.info.getId());
+            } else {
+                service.createSession(channels[1], callback, sessionState.info.getId());
+            }
         } catch (RemoteException e) {
             Slog.e(TAG, "error in createSession", e);
             removeSessionStateLocked(sessionToken, userId);
@@ -632,7 +641,11 @@
                 if (sessionToken == userState.mainSessionToken) {
                     setMainLocked(sessionToken, false, callingUid, userId);
                 }
-                sessionState.session.release();
+                if (sessionState.isRecordingSession) {
+                    sessionState.session.disconnect();
+                } else {
+                    sessionState.session.release();
+                }
             }
         } catch (RemoteException | SessionNotFoundException e) {
             Slog.e(TAG, "error in releaseSession", e);
@@ -766,6 +779,21 @@
         }
     }
 
+    private void notifyTvInputInfoChanged(UserState userState, String inputId,
+            TvInputInfo inputInfo) {
+        if (DEBUG) {
+            Slog.d(TAG, "notifyTvInputInfoChanged(inputId=" + inputId + ", inputInfo=" + inputInfo
+                    + ")");
+        }
+        for (ITvInputManagerCallback callback : userState.callbackSet) {
+            try {
+                callback.onTvInputInfoChanged(inputId, inputInfo);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "failed to report changed input info to callback", e);
+            }
+        }
+    }
+
     private void setStateLocked(String inputId, int state, int userId) {
         UserState userState = getOrCreateUserStateLocked(userId);
         TvInputState inputState = userState.inputMap.get(inputId);
@@ -1005,7 +1033,7 @@
 
         @Override
         public void createSession(final ITvInputClient client, final String inputId,
-                int seq, int userId) {
+                boolean isRecordingSession, int seq, int userId) {
             final int callingUid = Binder.getCallingUid();
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
                     userId, "createSession");
@@ -1033,8 +1061,8 @@
 
                     // Create a new session token and a session state.
                     IBinder sessionToken = new Binder();
-                    SessionState sessionState = new SessionState(sessionToken, info, client,
-                            seq, callingUid, resolvedUserId);
+                    SessionState sessionState = new SessionState(sessionToken, info,
+                            isRecordingSession, client, seq, callingUid, resolvedUserId);
 
                     // Add them to the global session state map of the current user.
                     userState.sessionStateMap.put(sessionToken, sessionState);
@@ -1375,6 +1403,26 @@
         }
 
         @Override
+        public void timeShiftPlay(IBinder sessionToken, final Uri recordedProgramUri, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
+                    userId, "timeShiftPlay");
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    try {
+                        getSessionLocked(sessionToken, callingUid, resolvedUserId).timeShiftPlay(
+                                recordedProgramUri);
+                    } catch (RemoteException | SessionNotFoundException e) {
+                        Slog.e(TAG, "error in timeShiftPlay", e);
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @Override
         public void timeShiftPause(IBinder sessionToken, int userId) {
             final int callingUid = Binder.getCallingUid();
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
@@ -1383,8 +1431,7 @@
             try {
                 synchronized (mLock) {
                     try {
-                        getSessionLocked(sessionToken, callingUid, resolvedUserId)
-                                .timeShiftPause();
+                        getSessionLocked(sessionToken, callingUid, resolvedUserId).timeShiftPause();
                     } catch (RemoteException | SessionNotFoundException e) {
                         Slog.e(TAG, "error in timeShiftPause", e);
                     }
@@ -1477,6 +1524,64 @@
         }
 
         @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) {
+            final int callingUid = Binder.getCallingUid();
+            final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
+                    userId, "startRecording");
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    try {
+                        getSessionLocked(sessionToken, callingUid, resolvedUserId).startRecording();
+                    } catch (RemoteException | SessionNotFoundException e) {
+                        Slog.e(TAG, "error in startRecording", e);
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @Override
+        public void stopRecording(IBinder sessionToken, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
+                    userId, "stopRecording");
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    try {
+                        getSessionLocked(sessionToken, callingUid, resolvedUserId).stopRecording();
+                    } catch (RemoteException | SessionNotFoundException e) {
+                        Slog.e(TAG, "error in stopRecording", e);
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @Override
         public List<TvInputHardwareInfo> getHardwareList() throws RemoteException {
             if (mContext.checkCallingPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
                     != PackageManager.PERMISSION_GRANTED) {
@@ -1912,6 +2017,7 @@
 
     private final class SessionState implements IBinder.DeathRecipient {
         private final TvInputInfo info;
+        private final boolean isRecordingSession;
         private final ITvInputClient client;
         private final int seq;
         private final int callingUid;
@@ -1922,10 +2028,11 @@
         // Not null if this session represents an external device connected to a hardware TV input.
         private IBinder hardwareSessionToken;
 
-        private SessionState(IBinder sessionToken, TvInputInfo info, ITvInputClient client,
-                int seq, int callingUid, int userId) {
+        private SessionState(IBinder sessionToken, TvInputInfo info, boolean isRecordingSession,
+                ITvInputClient client, int seq, int callingUid, int userId) {
             this.sessionToken = sessionToken;
             this.info = info;
+            this.isRecordingSession = isRecordingSession;
             this.client = client;
             this.seq = seq;
             this.callingUid = callingUid;
@@ -2126,6 +2233,18 @@
                 }
             }
         }
+
+        @Override
+        public void setTvInputInfo(String inputId, TvInputInfo inputInfo) {
+            ensureValidInput(inputInfo);
+            synchronized (mLock) {
+                if (DEBUG) {
+                    Slog.d(TAG, "setTvInputInfo(" + inputInfo + ")");
+                }
+                UserState userState = getOrCreateUserStateLocked(mUserId);
+                notifyTvInputInfoChanged(userState, inputId, inputInfo);
+            }
+        }
     }
 
     private final class SessionCallback extends ITvInputSessionCallback.Stub {
@@ -2393,6 +2512,78 @@
                 }
             }
         }
+
+        // For the recording session only
+        @Override
+        public void onConnected() {
+            synchronized (mLock) {
+                if (DEBUG) {
+                    Slog.d(TAG, "onConnected()");
+                }
+                if (mSessionState.session == null || mSessionState.client == null) {
+                    return;
+                }
+                try {
+                    mSessionState.client.onConnected(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);
+                }
+            }
+        }
+
+        // For the recording session only
+        @Override
+        public void onRecordingStopped(Uri recordedProgramUri) {
+            synchronized (mLock) {
+                if (DEBUG) {
+                    Slog.d(TAG, "onRecordingStopped()");
+                }
+                if (mSessionState.session == null || mSessionState.client == null) {
+                    return;
+                }
+                try {
+                    mSessionState.client.onRecordingStopped(recordedProgramUri, mSessionState.seq);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "error in onRecordingStopped", e);
+                }
+            }
+        }
+
+        // For the recording session only
+        @Override
+        public void onError(int error) {
+            synchronized (mLock) {
+                if (DEBUG) {
+                    Slog.d(TAG, "onError()");
+                }
+                if (mSessionState.session == null || mSessionState.client == null) {
+                    return;
+                }
+                try {
+                    mSessionState.client.onError(error, mSessionState.seq);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "error in onError", e);
+                }
+            }
+        }
     }
 
     private static final class WatchLogHandler extends Handler {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 87d0700..39983dd 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -92,6 +92,8 @@
 import com.android.internal.R;
 import com.android.server.EventLogTags;
 
+import libcore.io.IoUtils;
+
 public class WallpaperManagerService extends IWallpaperManager.Stub {
     static final String TAG = "WallpaperManagerService";
     static final boolean DEBUG = false;
@@ -170,6 +172,12 @@
     WallpaperData mLastWallpaper;
 
     /**
+     * ID of the current wallpaper, changed every time anything sets a wallpaper.
+     * This is used for external detection of wallpaper update activity.
+     */
+    int mWallpaperId;
+
+    /**
      * Name of the component used to display bitmap wallpapers from either the gallery or
      * built-in wallpapers.
      */
@@ -205,6 +213,11 @@
          */
         ComponentName nextWallpaperComponent;
 
+        /**
+         * The ID of this wallpaper
+         */
+        int wallpaperId;
+
         WallpaperConnection connection;
         long lastDiedTime;
         boolean wallpaperUpdating;
@@ -227,6 +240,13 @@
         }
     }
 
+    int makeWallpaperIdLocked() {
+        do {
+            ++mWallpaperId;
+        } while (mWallpaperId == 0);
+        return mWallpaperId;
+    }
+
     class WallpaperConnection extends IWallpaperConnection.Stub
             implements ServiceConnection {
         final WallpaperInfo mInfo;
@@ -333,7 +353,7 @@
         public ParcelFileDescriptor setWallpaper(String name) {
             synchronized (mLock) {
                 if (mWallpaper.connection == this) {
-                    return updateWallpaperBitmapLocked(name, mWallpaper);
+                    return updateWallpaperBitmapLocked(name, mWallpaper, null);
                 }
                 return null;
             }
@@ -848,18 +868,26 @@
         }
     }
 
-    public ParcelFileDescriptor setWallpaper(String name, String callingPackage) {
+    @Override
+    public ParcelFileDescriptor setWallpaper(String name, String callingPackage, Bundle extras,
+            int which) {
         checkPermission(android.Manifest.permission.SET_WALLPAPER);
+
+        if (which == 0) {
+            return null;
+        }
+
         if (!isWallpaperSupported(callingPackage)) {
             return null;
         }
+
         synchronized (mLock) {
             if (DEBUG) Slog.v(TAG, "setWallpaper");
             int userId = UserHandle.getCallingUserId();
             WallpaperData wallpaper = getWallpaperSafeLocked(userId);
             final long ident = Binder.clearCallingIdentity();
             try {
-                ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
+                ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper, extras);
                 if (pfd != null) {
                     wallpaper.imageWallpaperPending = true;
                 }
@@ -870,7 +898,8 @@
         }
     }
 
-    ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
+    ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper,
+            Bundle extras) {
         if (name == null) name = "";
         try {
             File dir = getWallpaperDir(wallpaper.userId);
@@ -888,6 +917,14 @@
                 return null;
             }
             wallpaper.name = name;
+            wallpaper.wallpaperId = makeWallpaperIdLocked();
+            if (extras != null) {
+                extras.putInt(WallpaperManager.EXTRA_NEW_WALLPAPER_ID, wallpaper.wallpaperId);
+            }
+            if (DEBUG) {
+                Slog.v(TAG, "updateWallpaperBitmapLocked() : id=" + wallpaper.wallpaperId
+                        + " name=" + name);
+            }
             return fd;
         } catch (FileNotFoundException e) {
             Slog.w(TAG, "Error setting wallpaper", e);
@@ -1156,6 +1193,7 @@
             out.startDocument(null, true);
 
             out.startTag(null, "wp");
+            out.attribute(null, "id", Integer.toString(wallpaper.wallpaperId));
             out.attribute(null, "width", Integer.toString(wallpaper.width));
             out.attribute(null, "height", Integer.toString(wallpaper.height));
             if (wallpaper.padding.left != 0) {
@@ -1184,13 +1222,7 @@
             stream.close();
             journal.commit();
         } catch (IOException e) {
-            try {
-                if (stream != null) {
-                    stream.close();
-                }
-            } catch (IOException ex) {
-                // Ignore
-            }
+            IoUtils.closeQuietly(stream);
             journal.rollback();
         }
     }
@@ -1259,6 +1291,16 @@
                 if (type == XmlPullParser.START_TAG) {
                     String tag = parser.getName();
                     if ("wp".equals(tag)) {
+                        final String idString = parser.getAttributeValue(null, "id");
+                        if (idString != null) {
+                            final int id = wallpaper.wallpaperId = Integer.parseInt(idString);
+                            if (id > mWallpaperId) {
+                                mWallpaperId = id;
+                            }
+                        } else {
+                            wallpaper.wallpaperId = makeWallpaperIdLocked();
+                        }
+
                         wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
                         wallpaper.height = Integer.parseInt(parser
                                 .getAttributeValue(null, "height"));
@@ -1301,19 +1343,21 @@
         } catch (IndexOutOfBoundsException e) {
             Slog.w(TAG, "failed parsing " + file + " " + e);
         }
-        try {
-            if (stream != null) {
-                stream.close();
-            }
-        } catch (IOException e) {
-            // Ignore
-        }
+        IoUtils.closeQuietly(stream);
 
         if (!success) {
             wallpaper.width = -1;
             wallpaper.height = -1;
             wallpaper.padding.set(0, 0, 0, 0);
             wallpaper.name = "";
+        } else {
+            if (wallpaper.wallpaperId <= 0) {
+                wallpaper.wallpaperId = makeWallpaperIdLocked();
+                if (DEBUG) {
+                    Slog.w(TAG, "Didn't set wallpaper id in loadSettingsLocked(" + userId
+                            + "); now " + wallpaper.wallpaperId);
+                }
+            }
         }
 
         // We always want to have some reasonable width hint.
@@ -1346,6 +1390,7 @@
         synchronized (mLock) {
             loadSettingsLocked(0);
             wallpaper = mWallpaperMap.get(0);
+            wallpaper.wallpaperId = makeWallpaperIdLocked();    // always bump id at restore
             if (wallpaper.nextWallpaperComponent != null
                     && !wallpaper.nextWallpaperComponent.equals(mImageWallpaper)) {
                 if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
@@ -1366,7 +1411,8 @@
                     if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
                     success = restoreNamedResourceLocked(wallpaper);
                 }
-                if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
+                if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success
+                        + " id=" + wallpaper.wallpaperId);
                 if (success) {
                     bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
                             wallpaper, null);
@@ -1442,16 +1488,10 @@
                 } catch (IOException e) {
                     Slog.e(TAG, "IOException while restoring wallpaper ", e);
                 } finally {
-                    if (res != null) {
-                        try {
-                            res.close();
-                        } catch (IOException ex) {}
-                    }
+                    IoUtils.closeQuietly(res);
                     if (fos != null) {
                         FileUtils.sync(fos);
-                        try {
-                            fos.close();
-                        } catch (IOException ex) {}
+                        IoUtils.closeQuietly(fos);
                     }
                 }
             }
@@ -1474,7 +1514,8 @@
             pw.println("Current Wallpaper Service state:");
             for (int i = 0; i < mWallpaperMap.size(); i++) {
                 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
-                pw.println(" User " + wallpaper.userId + ":");
+                pw.print(" User "); pw.print(wallpaper.userId);
+                pw.print(": id="); pw.println(wallpaper.wallpaperId);
                 pw.print("  mWidth=");
                     pw.print(wallpaper.width);
                     pw.print(" mHeight=");
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 65b91f7..d1c0881 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -28,6 +28,7 @@
 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;
@@ -36,6 +37,8 @@
 import android.view.Display;
 import android.view.DragEvent;
 import android.view.InputChannel;
+import android.view.InputDevice;
+import android.view.PointerIcon;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.WindowManager;
@@ -72,6 +75,7 @@
     int mUid;
     ClipData mData;
     ClipDescription mDataDescription;
+    int mTouchSource;
     boolean mDragResult;
     float mOriginalAlpha;
     float mOriginalX, mOriginalY;
@@ -342,6 +346,7 @@
 
     private void cleanUpDragLw() {
         broadcastDragEndedLw();
+        restorePointerIconLw();
 
         // stop intercepting input
         unregister();
@@ -522,16 +527,28 @@
             ClipDescription description, ClipData data,
             IDropPermissions dropPermissions,
             boolean result) {
-        float winX = x - win.mFrame.left;
-        float winY = y - win.mFrame.top;
-        if (win.mEnforceSizeCompat) {
-            winX *= win.mGlobalScale;
-            winY *= win.mGlobalScale;
-        }
+        final float winX = translateToWindowX(win, x);
+        final float winY = translateToWindowY(win, 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;
@@ -576,4 +593,32 @@
         set.start();  // Will start on the first call to getTransformation.
         return set;
     }
+
+    private boolean isFromSource(int source) {
+        return (mTouchSource & source) == source;
+    }
+
+    void overridePointerIconLw(int touchSource) {
+        mTouchSource = touchSource;
+        if (isFromSource(InputDevice.SOURCE_MOUSE)) {
+            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/DropPermissionsHandler.java b/services/core/java/com/android/server/wm/DropPermissionsHandler.java
index 68cfaab..5889fb8 100644
--- a/services/core/java/com/android/server/wm/DropPermissionsHandler.java
+++ b/services/core/java/com/android/server/wm/DropPermissionsHandler.java
@@ -27,7 +27,7 @@
 
 import java.util.ArrayList;
 
-class DropPermissionsHandler extends IDropPermissions.Stub {
+class DropPermissionsHandler extends IDropPermissions.Stub implements IBinder.DeathRecipient {
 
     private final int mSourceUid;
     private final String mTargetPackage;
@@ -38,6 +38,7 @@
     private final ArrayList<Uri> mUris = new ArrayList<Uri>();
 
     private IBinder mActivityToken = null;
+    private IBinder mPermissionOwnerToken = null;
 
     DropPermissionsHandler(ClipData clipData, int sourceUid, String targetPackage, int mode,
             int sourceUserId, int targetUserId) {
@@ -52,7 +53,7 @@
 
     @Override
     public void take(IBinder activityToken) throws RemoteException {
-        if (mActivityToken != null) {
+        if (mActivityToken != null || mPermissionOwnerToken != null) {
             return;
         }
         mActivityToken = activityToken;
@@ -61,6 +62,10 @@
         IBinder permissionOwner = ActivityManagerNative.getDefault().
                 getUriPermissionOwnerForActivity(mActivityToken);
 
+        doTake(permissionOwner);
+    }
+
+    private void doTake(IBinder permissionOwner) throws RemoteException {
         long origId = Binder.clearCallingIdentity();
         try {
             for (int i = 0; i < mUris.size(); i++) {
@@ -74,20 +79,37 @@
     }
 
     @Override
+    public void takeTransient(IBinder permissionOwnerToken) throws RemoteException {
+        if (mActivityToken != null || mPermissionOwnerToken != null) {
+            return;
+        }
+        mPermissionOwnerToken = permissionOwnerToken;
+        mPermissionOwnerToken.linkToDeath(this, 0);
+
+        doTake(mPermissionOwnerToken);
+    }
+
+    @Override
     public void release() throws RemoteException {
-        if (mActivityToken == null) {
+        if (mActivityToken == null && mPermissionOwnerToken == null) {
             return;
         }
 
         IBinder permissionOwner = null;
-        try {
-            permissionOwner = ActivityManagerNative.getDefault().
-                    getUriPermissionOwnerForActivity(mActivityToken);
-        } catch (Exception e) {
-            // Activity is destroyed, permissions already revoked.
-            return;
-        } finally {
-            mActivityToken = null;
+        if (mActivityToken != null) {
+            try {
+                permissionOwner = ActivityManagerNative.getDefault().
+                        getUriPermissionOwnerForActivity(mActivityToken);
+            } catch (Exception e) {
+                // Activity is destroyed, permissions already revoked.
+                return;
+            } finally {
+                mActivityToken = null;
+            }
+        } else {
+            permissionOwner = mPermissionOwnerToken;
+            mPermissionOwnerToken.unlinkToDeath(this, 0);
+            mPermissionOwnerToken = null;
         }
 
         for (int i = 0; i < mUris.size(); ++i) {
@@ -95,4 +117,13 @@
                     permissionOwner, mUris.get(i), mMode, mSourceUserId);
         }
     }
+
+    @Override
+    public void binderDied() {
+        try {
+            release();
+        } catch (RemoteException e) {
+            // Cannot happen, local call.
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index d8cbbab..a8d974f 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -283,7 +283,7 @@
     }
 
     public boolean performDrag(IWindow window, IBinder dragToken,
-            float touchX, float touchY, float thumbCenterX, float thumbCenterY,
+            int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
             ClipData data) {
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "perform drag: win=" + window + " data=" + data);
@@ -336,6 +336,7 @@
 
             mService.mDragState.mData = data;
             mService.mDragState.broadcastDragStartedLw(touchX, touchY);
+            mService.mDragState.overridePointerIconLw(touchSource);
 
             // remember the thumb offsets for later
             mService.mDragState.mThumbOffsetX = thumbCenterX;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1021411..93a1015 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2193,7 +2193,7 @@
             // need to see about starting one.
             wasVisible = win.isWinVisibleLw();
 
-            if (wasVisible && appToken != null && appToken.appDied) {
+            if (win.shouldKeepVisibleDeadAppWindow()) {
                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                         "Not removing " + win + " because app died while it's visible");
 
@@ -5349,9 +5349,31 @@
                 rebuildAppWindowListLocked(displayContent);
             }
             mWindowPlacerLocked.performSurfacePlacement();
+
+            // Notify whether the docked stack exists for the current user
+            getDefaultDisplayContentLocked().mDividerControllerLocked
+                    .notifyDockedStackExistsChanged(hasDockedTasksForUser(newUserId));
         }
     }
 
+    /**
+     * Returns whether there is a docked task for the current user.
+     */
+    boolean hasDockedTasksForUser(int userId) {
+        final TaskStack stack = mStackIdToStack.get(DOCKED_STACK_ID);
+        if (stack == null) {
+            return false;
+        }
+
+        final ArrayList<Task> tasks = stack.getTasks();
+        boolean hasUserTask = false;
+        for (int i = tasks.size() - 1; i >= 0 && !hasUserTask; i--) {
+            final Task task = tasks.get(i);
+            hasUserTask = (task.mUserId == userId);
+        }
+        return hasUserTask;
+    }
+
     /* Called by WindowState */
     boolean isCurrentProfileLocked(int userId) {
         if (userId == mCurrentUserId) return true;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index dca7735..e8de90c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1615,6 +1615,27 @@
         }
     }
 
+    /**
+     * Returns true if this window is visible and belongs to a dead app and shouldn't be removed,
+     * because we want to preserve its location on screen to be re-activated later when the user
+     * interacts with it.
+     */
+    boolean shouldKeepVisibleDeadAppWindow() {
+        if (!isWinVisibleLw() || mAppToken == null || !mAppToken.appDied) {
+            // Not a visible app window or the app isn't dead.
+            return false;
+        }
+
+        if (mAttrs.type == TYPE_APPLICATION_STARTING) {
+            // We don't keep starting windows since they were added by the window manager before
+            // the app even launched.
+            return false;
+        }
+
+        final TaskStack stack = getStack();
+        return stack != null && StackId.keepVisibleDeadAppWindowOnScreen(stack.mStackId);
+    }
+
     /** @return true if this window desires key events. */
     boolean canReceiveKeys() {
         return isVisibleOrAdding()
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f68a299..fe62d15 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -132,7 +132,6 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
-import com.android.server.pm.UserManagerService;
 import com.android.server.pm.UserRestrictionsUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -181,6 +180,14 @@
     private static final String DO_NOT_ASK_CREDENTIALS_ON_BOOT_XML =
             "do-not-ask-credentials-on-boot";
 
+    private static final String TAG_AFFILIATION_ID = "affiliation-id";
+
+    private static final String TAG_ADMIN_BROADCAST_PENDING = "admin-broadcast-pending";
+
+    private static final String ATTR_VALUE = "value";
+
+    private static final String TAG_INITIALIZATION_BUNDLE = "initialization-bundle";
+
     private static final int REQUEST_EXPIRE_PASSWORD = 5571;
 
     private static final long MS_PER_DAY = 86400 * 1000;
@@ -195,6 +202,7 @@
 
     private static final String ATTR_PERMISSION_PROVIDER = "permission-provider";
     private static final String ATTR_SETUP_COMPLETE = "setup-complete";
+    private static final String ATTR_PROVISIONING_STATE = "provisioning-state";
     private static final String ATTR_PERMISSION_POLICY = "permission-policy";
 
     private static final String ATTR_DELEGATED_CERT_INSTALLER = "delegated-cert-installer";
@@ -242,16 +250,20 @@
         GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.WIFI_ON);
     }
 
-    // Keyguard features that when set of a profile will affect the profiles
-    // parent user.
+    /** Keyguard features that when set on a profile will affect the profiles parent user. */
     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 are allowed to be set on a managed profile
+    /** Keyguard features that when set on a profile affect the profile content or challenge only */
+    private static final int PROFILE_KEYGUARD_FEATURES_AFFECT_PROFILE =
+            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
-            | DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+            PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER | PROFILE_KEYGUARD_FEATURES_AFFECT_PROFILE;
 
     final Context mContext;
     final Injector mInjector;
@@ -353,6 +365,7 @@
         int mPasswordOwner = -1;
         long mLastMaximumTimeToLock = -1;
         boolean mUserSetupComplete = false;
+        int mUserProvisioningState;
         int mPermissionPolicy;
 
         final ArrayMap<ComponentName, ActiveAdmin> mAdminMap = new ArrayMap<>();
@@ -372,6 +385,12 @@
 
         String mApplicationRestrictionsManagingPackage;
 
+        Set<String> mAffiliationIds = new ArraySet<>();
+
+        // Used for initialization of users created by createAndManageUsers.
+        boolean mAdminBroadcastPending = false;
+        PersistableBundle mInitBundle = null;
+
         public DevicePolicyData(int userHandle) {
             mUserHandle = userHandle;
         }
@@ -420,16 +439,15 @@
             }
             if (Intent.ACTION_USER_REMOVED.equals(action)) {
                 removeUserData(userHandle);
-            } else if (Intent.ACTION_USER_STARTED.equals(action)
-                    || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
-
-                if (Intent.ACTION_USER_STARTED.equals(action)) {
+            } else if (Intent.ACTION_USER_STARTED.equals(action)) {
+                synchronized (DevicePolicyManagerService.this) {
                     // Reset the policy data
-                    synchronized (DevicePolicyManagerService.this) {
-                        mUserData.remove(userHandle);
-                    }
+                    mUserData.remove(userHandle);
+                    sendAdminEnabledBroadcastLocked(userHandle);
                 }
                 handlePackagesChanged(null /* check all admins */, userHandle);
+            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
+                handlePackagesChanged(null /* check all admins */, userHandle);
             } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)
                     || (Intent.ACTION_PACKAGE_ADDED.equals(action)
                             && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false))) {
@@ -453,6 +471,7 @@
         private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture";
         private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
         private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
+        private static final String TAG_FORCE_EPHEMERAL_USERS = "force_ephemeral_users";
         private static final String TAG_ACCOUNT_TYPE = "account-type";
         private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES
                 = "permitted-accessiblity-services";
@@ -541,6 +560,7 @@
         boolean disableBluetoothContactSharing = true;
         boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
         boolean requireAutoTime = false; // Can only be set by a device owner.
+        boolean forceEphemeralUsers = false; // Can only be set by a device owner.
 
         ActiveAdmin parentAdmin;
         final boolean isParent;
@@ -592,12 +612,18 @@
         }
 
         ActiveAdmin getParentActiveAdmin() {
-            if (parentAdmin == null && !isParent) {
+            Preconditions.checkState(!isParent);
+
+            if (parentAdmin == null) {
                 parentAdmin = new ActiveAdmin(info, /* parent */ true);
             }
             return parentAdmin;
         }
 
+        boolean hasParentActiveAdmin() {
+            return parentAdmin != null;
+        }
+
         int getUid() { return info.getActivityInfo().applicationInfo.uid; }
 
         public UserHandle getUserHandle() {
@@ -725,6 +751,11 @@
                 out.attribute(null, ATTR_VALUE, Boolean.toString(requireAutoTime));
                 out.endTag(null, TAG_REQUIRE_AUTO_TIME);
             }
+            if (forceEphemeralUsers) {
+                out.startTag(null, TAG_FORCE_EPHEMERAL_USERS);
+                out.attribute(null, ATTR_VALUE, Boolean.toString(forceEphemeralUsers));
+                out.endTag(null, TAG_FORCE_EPHEMERAL_USERS);
+            }
             if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
                 out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES);
                 out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures));
@@ -895,7 +926,10 @@
                     disableScreenCapture = Boolean.parseBoolean(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_REQUIRE_AUTO_TIME.equals(tag)) {
-                    requireAutoTime= Boolean.parseBoolean(
+                    requireAutoTime = Boolean.parseBoolean(
+                            parser.getAttributeValue(null, ATTR_VALUE));
+                } else if (TAG_FORCE_EPHEMERAL_USERS.equals(tag)) {
+                    forceEphemeralUsers = Boolean.parseBoolean(
                             parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
                     disabledKeyguardFeatures = Integer.parseInt(
@@ -929,6 +963,8 @@
                         Log.w(LOG_TAG, "Missing text when loading long support message");
                     }
                 } else if (TAG_PARENT_ADMIN.equals(tag)) {
+                    Preconditions.checkState(!isParent);
+
                     parentAdmin = new ActiveAdmin(info, /* parent */ true);
                     parentAdmin.readFromXml(parser);
                 } else if (TAG_ORGANIZATION_COLOR.equals(tag)) {
@@ -1124,6 +1160,8 @@
                     pw.println(disableScreenCapture);
             pw.print(prefix); pw.print("requireAutoTime=");
                     pw.println(requireAutoTime);
+            pw.print(prefix); pw.print("forceEphemeralUsers=");
+                    pw.println(forceEphemeralUsers);
             pw.print(prefix); pw.print("disabledKeyguardFeatures=");
                     pw.println(disabledKeyguardFeatures);
             pw.print(prefix); pw.print("crossProfileWidgetProviders=");
@@ -1142,6 +1180,12 @@
             }
             pw.print(prefix); pw.println("userRestrictions:");
             UserRestrictionsUtils.dumpRestrictions(pw, prefix + "  ", userRestrictions);
+            pw.print(prefix); pw.print("isParent=");
+                    pw.println(isParent);
+            if (parentAdmin != null) {
+                pw.print(prefix);  pw.println("parentAdmin:");
+                parentAdmin.dump(prefix + "  ", pw);
+            }
         }
     }
 
@@ -1401,7 +1445,7 @@
         mIPackageManager = Preconditions.checkNotNull(injector.getIPackageManager());
 
         mLocalService = new LocalService();
-        mLockPatternUtils = new LockPatternUtils(mContext);
+        mLockPatternUtils = injector.newLockPatternUtils();
 
         mHasFeature = mContext.getPackageManager()
                 .hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
@@ -1658,8 +1702,8 @@
      * Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration
      * reminders.  Clears alarm if no expirations are configured.
      */
-    protected void setExpirationAlarmCheckLocked(Context context, DevicePolicyData policy) {
-        final long expiration = getPasswordExpirationLocked(null, policy.mUserHandle);
+    private void setExpirationAlarmCheckLocked(Context context, int userHandle) {
+        final long expiration = getPasswordExpirationLocked(null, userHandle, /* parent */ false);
         final long now = System.currentTimeMillis();
         final long timeToExpire = expiration - now;
         final long alarmTime;
@@ -1685,7 +1729,7 @@
             PendingIntent pi = PendingIntent.getBroadcastAsUser(context, REQUEST_EXPIRE_PASSWORD,
                     new Intent(ACTION_EXPIRED_PASSWORD_NOTIFICATION),
                     PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT,
-                    new UserHandle(policy.mUserHandle));
+                    UserHandle.of(userHandle));
             am.cancel(pi);
             if (alarmTime != 0) {
                 am.set(AlarmManager.RTC, alarmTime, pi);
@@ -1705,6 +1749,17 @@
         return null;
     }
 
+    ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle, boolean parent) {
+        if (parent) {
+            enforceManagedProfile(userHandle, "call APIs on the parent profile");
+        }
+        ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+        if (admin != null && parent) {
+            admin = admin.getParentActiveAdmin();
+        }
+        return admin;
+    }
+
     ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy)
             throws SecurityException {
         final int callingUid = mInjector.binderGetCallingUid();
@@ -1735,6 +1790,15 @@
         }
     }
 
+    ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy, boolean parent)
+            throws SecurityException {
+        if (parent) {
+            enforceManagedProfile(mInjector.userHandleGetCallingUserId(),
+                    "call APIs on the parent profile");
+        }
+        ActiveAdmin admin = getActiveAdminForCallerLocked(who, reqPolicy);
+        return parent ? admin.getParentActiveAdmin() : admin;
+    }
     /**
      * Find the admin for the component and userId bit of the uid, then check
      * the admin's uid matches the uid.
@@ -1854,6 +1918,18 @@
         }
     }
 
+    /**
+     * Sends a broadcast to each profile that share the password unlock with the given user id.
+     */
+    private void sendAdminCommandForLockscreenPoliciesLocked(
+            String action, int reqPolicy, int userHandle) {
+        if (isSeparateProfileChallengeEnabled(userHandle)) {
+            sendAdminCommandLocked(action, reqPolicy, userHandle);
+        } else {
+            sendAdminCommandToSelfAndProfilesLocked(action, reqPolicy, userHandle);
+        }
+    }
+
     void removeActiveAdminLocked(final ComponentName adminReceiver, final int userHandle) {
         final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
         if (admin != null) {
@@ -1877,7 +1953,7 @@
                                     resetGlobalProxyLocked(getUserData(userHandle));
                                 }
                                 saveSettingsLocked(userHandle);
-                                updateMaximumTimeToLockLocked(policy);
+                                updateMaximumTimeToLockLocked(userHandle);
                                 policy.mRemovingAdmins.remove(adminReceiver);
                             }
                             // The removed admin might have disabled camera, so update user
@@ -1955,6 +2031,10 @@
                 out.attribute(null, ATTR_SETUP_COMPLETE,
                         Boolean.toString(true));
             }
+            if (policy.mUserProvisioningState != DevicePolicyManager.STATE_USER_UNMANAGED) {
+                out.attribute(null, ATTR_PROVISIONING_STATE,
+                        Integer.toString(policy.mUserProvisioningState));
+            }
             if (policy.mPermissionPolicy != DevicePolicyManager.PERMISSION_POLICY_PROMPT) {
                 out.attribute(null, ATTR_PERMISSION_POLICY,
                         Integer.toString(policy.mPermissionPolicy));
@@ -2026,6 +2106,25 @@
                 out.endTag(null, DO_NOT_ASK_CREDENTIALS_ON_BOOT_XML);
             }
 
+            for (String id : policy.mAffiliationIds) {
+                out.startTag(null, TAG_AFFILIATION_ID);
+                out.attribute(null, "id", id);
+                out.endTag(null, TAG_AFFILIATION_ID);
+            }
+
+            if (policy.mAdminBroadcastPending) {
+                out.startTag(null, TAG_ADMIN_BROADCAST_PENDING);
+                out.attribute(null, ATTR_VALUE,
+                        Boolean.toString(policy.mAdminBroadcastPending));
+                out.endTag(null, TAG_ADMIN_BROADCAST_PENDING);
+            }
+
+            if (policy.mInitBundle != null) {
+                out.startTag(null, TAG_INITIALIZATION_BUNDLE);
+                policy.mInitBundle.saveToXml(out);
+                out.endTag(null, TAG_INITIALIZATION_BUNDLE);
+            }
+
             out.endTag(null, "policies");
 
             out.endDocument();
@@ -2034,7 +2133,7 @@
             stream.close();
             journal.commit();
             sendChangedNotification(userHandle);
-        } catch (IOException e) {
+        } catch (XmlPullParserException | IOException e) {
             Slog.w(LOG_TAG, "failed writing file", e);
             try {
                 if (stream != null) {
@@ -2086,6 +2185,10 @@
             if (userSetupComplete != null && Boolean.toString(true).equals(userSetupComplete)) {
                 policy.mUserSetupComplete = true;
             }
+            String provisioningState = parser.getAttributeValue(null, ATTR_PROVISIONING_STATE);
+            if (!TextUtils.isEmpty(provisioningState)) {
+                policy.mUserProvisioningState = Integer.parseInt(provisioningState);
+            }
             String permissionPolicy = parser.getAttributeValue(null, ATTR_PERMISSION_POLICY);
             if (!TextUtils.isEmpty(permissionPolicy)) {
                 policy.mPermissionPolicy = Integer.parseInt(permissionPolicy);
@@ -2100,6 +2203,7 @@
             policy.mLockTaskPackages.clear();
             policy.mAdminList.clear();
             policy.mAdminMap.clear();
+            policy.mAffiliationIds.clear();
             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -2157,6 +2261,13 @@
                             parser.getAttributeValue(null, ATTR_DISABLED));
                 } else if (DO_NOT_ASK_CREDENTIALS_ON_BOOT_XML.equals(tag)) {
                     policy.doNotAskCredentialsOnBoot = true;
+                } else if (TAG_AFFILIATION_ID.equals(tag)) {
+                    policy.mAffiliationIds.add(parser.getAttributeValue(null, "id"));
+                } else if (TAG_ADMIN_BROADCAST_PENDING.equals(tag)) {
+                    String pending = parser.getAttributeValue(null, ATTR_VALUE);
+                    policy.mAdminBroadcastPending = Boolean.toString(true).equals(pending);
+                } else if (TAG_INITIALIZATION_BUNDLE.equals(tag)) {
+                    policy.mInitBundle = PersistableBundle.restoreFromXml(parser);
                 } else {
                     Slog.w(LOG_TAG, "Unknown tag: " + tag);
                     XmlUtils.skipCurrentTag(parser);
@@ -2185,12 +2296,12 @@
         // never normally happen.
         final long identity = mInjector.binderClearCallingIdentity();
         try {
-            LockPatternUtils utils = mInjector.newLockPatternUtils();
-            if (utils.getActivePasswordQuality(userHandle) < policy.mActivePasswordQuality) {
+            int actualPasswordQuality = mLockPatternUtils.getActivePasswordQuality(userHandle);
+            if (actualPasswordQuality < policy.mActivePasswordQuality) {
                 Slog.w(LOG_TAG, "Active password quality 0x"
                         + Integer.toHexString(policy.mActivePasswordQuality)
                         + " does not match actual quality 0x"
-                        + Integer.toHexString(utils.getActivePasswordQuality(userHandle)));
+                        + Integer.toHexString(actualPasswordQuality));
                 policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
                 policy.mActivePasswordLength = 0;
                 policy.mActivePasswordUpperCase = 0;
@@ -2205,7 +2316,7 @@
         }
 
         validatePasswordOwnerLocked(policy);
-        updateMaximumTimeToLockLocked(policy);
+        updateMaximumTimeToLockLocked(userHandle);
         updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle);
         if (policy.mStatusBarDisabled) {
             setStatusBarDisabledInternal(policy.mStatusBarDisabled, userHandle);
@@ -2309,6 +2420,14 @@
         if (packageList != null) {
             mInjector.getPackageManagerInternal().setKeepUninstalledPackages(packageList);
         }
+
+        synchronized (this) {
+            // push the force-ephemeral-users policy to the user manager.
+            ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
+            if (deviceOwner != null) {
+                mUserManagerInternal.setForceEphemeralUsers(deviceOwner.forceEphemeralUsers);
+            }
+        }
     }
 
     private void ensureDeviceOwnerUserStarted() {
@@ -2369,25 +2488,21 @@
         synchronized (this) {
             final long now = System.currentTimeMillis();
 
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo ui : profiles) {
-                int profileUserHandle = ui.id;
-                final DevicePolicyData policy = getUserData(profileUserHandle);
-                final int count = policy.mAdminList.size();
-                if (count > 0) {
-                    for (int i = 0; i < count; i++) {
-                        final ActiveAdmin admin = policy.mAdminList.get(i);
-                        if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)
-                                && admin.passwordExpirationTimeout > 0L
-                                && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS
-                                && admin.passwordExpirationDate > 0L) {
-                            sendAdminCommandLocked(admin,
-                                    DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING);
-                        }
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+                    userHandle, /* parent */ false);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)
+                        && admin.passwordExpirationTimeout > 0L
+                        && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS
+                        && admin.passwordExpirationDate > 0L) {
+                    sendAdminCommandLocked(admin,
+                            DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING);
                 }
             }
-            setExpirationAlarmCheckLocked(mContext, getUserData(userHandle));
+            setExpirationAlarmCheckLocked(mContext, userHandle);
         }
     }
 
@@ -2656,7 +2771,7 @@
     @Override
     public boolean isSeparateProfileChallengeAllowed(int userHandle) {
         ComponentName profileOwner = getProfileOwner(userHandle);
-        return !isAdminApiLevelMOrBelow(profileOwner, userHandle);
+        return profileOwner != null && !isAdminApiLevelMOrBelow(profileOwner, userHandle);
     }
 
     @Override
@@ -2665,18 +2780,14 @@
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         validateQualityConstant(quality);
 
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
-            if (parent) {
-                ap = ap.getParentActiveAdmin();
-            }
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.passwordQuality != quality) {
                 ap.passwordQuality = quality;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
@@ -2691,46 +2802,55 @@
             int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
-                if (parent && admin != null) {
-                    admin = admin.getParentActiveAdmin();
-                }
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.passwordQuality : mode;
             }
 
-            if (isSeparateProfileChallengeEnabled(userHandle) && !parent) {
-                // If a Work Challenge is in use, only return its restrictions.
-                DevicePolicyData policy = getUserDataUnchecked(userHandle);
-                final int N = policy.mAdminList.size();
-                for (int i = 0; i < N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (mode < admin.passwordQuality) {
-                        mode = admin.passwordQuality;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (mode < admin.passwordQuality) {
+                    mode = admin.passwordQuality;
                 }
-            } else {
-                // Return strictest policy for this user and profiles that are visible from this
-                // user that do not use a separate work challenge.
-                // TODO: When there are separate parent restrictions the profile should just
-                // obey its own.
-                List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-                for (UserInfo userInfo : profiles) {
-                    // Only aggregate data for the parent profile plus the non-work challenge
-                    // enabled profiles.
-                    if (!(userInfo.isManagedProfile()
-                            && isSeparateProfileChallengeEnabled(userInfo.id))) {
-                        DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                        final int N = policy.mAdminList.size();
-                        for (int i = 0; i < N; i++) {
-                            ActiveAdmin admin = policy.mAdminList.get(i);
-                            if (mode < admin.passwordQuality) {
-                                mode = admin.passwordQuality;
-                            }
+            }
+            return mode;
+        }
+    }
+
+    private List<ActiveAdmin> getActiveAdminsForLockscreenPoliciesLocked(
+            int userHandle, boolean parent) {
+        if (!parent && isSeparateProfileChallengeEnabled(userHandle)) {
+            // If this user has a separate challenge, only return its restrictions.
+            return getUserDataUnchecked(userHandle).mAdminList;
+        } else {
+            // Return all admins for this user and the profiles that are visible from this
+            // user that do not use a separate work challenge.
+            ArrayList<ActiveAdmin> admins = new ArrayList<ActiveAdmin>();
+            for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
+                DevicePolicyData policy = getUserData(userInfo.id);
+                if (!isManagedProfile(userInfo.id)) {
+                    admins.addAll(policy.mAdminList);
+                } else {
+                    // For managed profiles, we always include the policies set on the parent
+                    // profile. Additionally, we include the ones set on the managed profile
+                    // if no separate challenge is in place.
+                    boolean hasSeparateChallenge = isSeparateProfileChallengeEnabled(userInfo.id);
+                    final int N = policy.mAdminList.size();
+                    for (int i = 0; i < N; i++) {
+                        ActiveAdmin admin = policy.mAdminList.get(i);
+                        if (admin.hasParentActiveAdmin()) {
+                            admins.add(admin.getParentActiveAdmin());
+                        }
+                        if (!hasSeparateChallenge) {
+                            admins.add(admin);
                         }
                     }
                 }
             }
-            return mode;
+            return admins;
         }
     }
 
@@ -2744,24 +2864,23 @@
     }
 
     @Override
-    public void setPasswordMinimumLength(ComponentName who, int length) {
+    public void setPasswordMinimumLength(ComponentName who, int length, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordLength != length) {
                 ap.minimumPasswordLength = length;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
     @Override
-    public int getPasswordMinimumLength(ComponentName who, int userHandle) {
+    public int getPasswordMinimumLength(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
@@ -2770,20 +2889,18 @@
             int length = 0;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.minimumPasswordLength : length;
             }
 
-            // Return strictest policy for this user and profiles that are visible from this user.
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i=0; i<N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (length < admin.minimumPasswordLength) {
-                        length = admin.minimumPasswordLength;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (length < admin.minimumPasswordLength) {
+                    length = admin.minimumPasswordLength;
                 }
             }
             return length;
@@ -2791,24 +2908,23 @@
     }
 
     @Override
-    public void setPasswordHistoryLength(ComponentName who, int length) {
+    public void setPasswordHistoryLength(ComponentName who, int length, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.passwordHistoryLength != length) {
                 ap.passwordHistoryLength = length;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
     @Override
-    public int getPasswordHistoryLength(ComponentName who, int userHandle) {
+    public int getPasswordHistoryLength(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
@@ -2817,37 +2933,36 @@
             int length = 0;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.passwordHistoryLength : length;
             }
 
-            // Return strictest policy for this user and profiles that are visible from this user.
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i = 0; i < N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (length < admin.passwordHistoryLength) {
-                        length = admin.passwordHistoryLength;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (length < admin.passwordHistoryLength) {
+                    length = admin.passwordHistoryLength;
                 }
             }
+
             return length;
         }
     }
 
     @Override
-    public void setPasswordExpirationTimeout(ComponentName who, long timeout) {
+    public void setPasswordExpirationTimeout(ComponentName who, long timeout, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
         Preconditions.checkArgumentNonnegative(timeout, "Timeout must be >= 0 ms");
-        final int userHandle = UserHandle.getCallingUserId();
+        final int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD, parent);
             // Calling this API automatically bumps the expiration date
             final long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
             ap.passwordExpirationDate = expiration;
@@ -2858,8 +2973,10 @@
                         .format(new Date(expiration)));
             }
             saveSettingsLocked(userHandle);
-            // in case this is the first one
-            setExpirationAlarmCheckLocked(mContext, getUserData(userHandle));
+
+            // in case this is the first one, set the alarm on the appropriate user.
+            int affectedUserHandle = parent ? getProfileParentId(userHandle) : userHandle;
+            setExpirationAlarmCheckLocked(mContext, affectedUserHandle);
         }
     }
 
@@ -2868,7 +2985,7 @@
      * Returns 0 if not configured.
      */
     @Override
-    public long getPasswordExpirationTimeout(ComponentName who, int userHandle) {
+    public long getPasswordExpirationTimeout(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0L;
         }
@@ -2877,20 +2994,19 @@
             long timeout = 0L;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.passwordExpirationTimeout : timeout;
             }
 
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i = 0; i < N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (timeout == 0L || (admin.passwordExpirationTimeout != 0L
-                            && timeout > admin.passwordExpirationTimeout)) {
-                        timeout = admin.passwordExpirationTimeout;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (timeout == 0L || (admin.passwordExpirationTimeout != 0L
+                        && timeout > admin.passwordExpirationTimeout)) {
+                    timeout = admin.passwordExpirationTimeout;
                 }
             }
             return timeout;
@@ -2971,59 +3087,56 @@
      * Return a single admin's expiration date/time, or the min (soonest) for all admins.
      * Returns 0 if not configured.
      */
-    private long getPasswordExpirationLocked(ComponentName who, int userHandle) {
+    private long getPasswordExpirationLocked(ComponentName who, int userHandle, boolean parent) {
         long timeout = 0L;
 
         if (who != null) {
-            ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+            ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
             return admin != null ? admin.passwordExpirationDate : timeout;
         }
 
-        List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-        for (UserInfo userInfo : profiles) {
-            DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-            final int N = policy.mAdminList.size();
-            for (int i = 0; i < N; i++) {
-                ActiveAdmin admin = policy.mAdminList.get(i);
-                if (timeout == 0L || (admin.passwordExpirationDate != 0
-                        && timeout > admin.passwordExpirationDate)) {
-                    timeout = admin.passwordExpirationDate;
-                }
+        // Return the strictest policy across all participating admins.
+        List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+        final int N = admins.size();
+        for (int i = 0; i < N; i++) {
+            ActiveAdmin admin = admins.get(i);
+            if (timeout == 0L || (admin.passwordExpirationDate != 0
+                    && timeout > admin.passwordExpirationDate)) {
+                timeout = admin.passwordExpirationDate;
             }
         }
         return timeout;
     }
 
     @Override
-    public long getPasswordExpiration(ComponentName who, int userHandle) {
+    public long getPasswordExpiration(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0L;
         }
         enforceFullCrossUsersPermission(userHandle);
         synchronized (this) {
-            return getPasswordExpirationLocked(who, userHandle);
+            return getPasswordExpirationLocked(who, userHandle, parent);
         }
     }
 
     @Override
-    public void setPasswordMinimumUpperCase(ComponentName who, int length) {
+    public void setPasswordMinimumUpperCase(ComponentName who, int length, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordUpperCase != length) {
                 ap.minimumPasswordUpperCase = length;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
     @Override
-    public int getPasswordMinimumUpperCase(ComponentName who, int userHandle) {
+    public int getPasswordMinimumUpperCase(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
@@ -3032,20 +3145,18 @@
             int length = 0;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.minimumPasswordUpperCase : length;
             }
 
-            // Return strictest policy for this user and profiles that are visible from this user.
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i=0; i<N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (length < admin.minimumPasswordUpperCase) {
-                        length = admin.minimumPasswordUpperCase;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (length < admin.minimumPasswordUpperCase) {
+                    length = admin.minimumPasswordUpperCase;
                 }
             }
             return length;
@@ -3053,21 +3164,20 @@
     }
 
     @Override
-    public void setPasswordMinimumLowerCase(ComponentName who, int length) {
+    public void setPasswordMinimumLowerCase(ComponentName who, int length, boolean parent) {
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordLowerCase != length) {
                 ap.minimumPasswordLowerCase = length;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
     @Override
-    public int getPasswordMinimumLowerCase(ComponentName who, int userHandle) {
+    public int getPasswordMinimumLowerCase(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
@@ -3076,20 +3186,18 @@
             int length = 0;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.minimumPasswordLowerCase : length;
             }
 
-            // Return strictest policy for this user and profiles that are visible from this user.
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i=0; i<N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (length < admin.minimumPasswordLowerCase) {
-                        length = admin.minimumPasswordLowerCase;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (length < admin.minimumPasswordLowerCase) {
+                    length = admin.minimumPasswordLowerCase;
                 }
             }
             return length;
@@ -3097,24 +3205,23 @@
     }
 
     @Override
-    public void setPasswordMinimumLetters(ComponentName who, int length) {
+    public void setPasswordMinimumLetters(ComponentName who, int length, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordLetters != length) {
                 ap.minimumPasswordLetters = length;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
     @Override
-    public int getPasswordMinimumLetters(ComponentName who, int userHandle) {
+    public int getPasswordMinimumLetters(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
@@ -3123,23 +3230,21 @@
             int length = 0;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.minimumPasswordLetters : length;
             }
 
-            // Return strictest policy for this user and profiles that are visible from this user.
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i=0; i<N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
-                        continue;
-                    }
-                    if (length < admin.minimumPasswordLetters) {
-                        length = admin.minimumPasswordLetters;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
+                    continue;
+                }
+                if (length < admin.minimumPasswordLetters) {
+                    length = admin.minimumPasswordLetters;
                 }
             }
             return length;
@@ -3147,24 +3252,23 @@
     }
 
     @Override
-    public void setPasswordMinimumNumeric(ComponentName who, int length) {
+    public void setPasswordMinimumNumeric(ComponentName who, int length, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordNumeric != length) {
                 ap.minimumPasswordNumeric = length;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
     @Override
-    public int getPasswordMinimumNumeric(ComponentName who, int userHandle) {
+    public int getPasswordMinimumNumeric(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
@@ -3173,23 +3277,21 @@
             int length = 0;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.minimumPasswordNumeric : length;
             }
 
-            // Return strictest policy for this user and profiles that are visible from this user.
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i = 0; i < N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
-                        continue;
-                    }
-                    if (length < admin.minimumPasswordNumeric) {
-                        length = admin.minimumPasswordNumeric;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
+                    continue;
+                }
+                if (length < admin.minimumPasswordNumeric) {
+                    length = admin.minimumPasswordNumeric;
                 }
             }
             return length;
@@ -3197,24 +3299,23 @@
     }
 
     @Override
-    public void setPasswordMinimumSymbols(ComponentName who, int length) {
+    public void setPasswordMinimumSymbols(ComponentName who, int length, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordSymbols != length) {
                 ap.minimumPasswordSymbols = length;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
     @Override
-    public int getPasswordMinimumSymbols(ComponentName who, int userHandle) {
+    public int getPasswordMinimumSymbols(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
@@ -3223,23 +3324,21 @@
             int length = 0;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.minimumPasswordSymbols : length;
             }
 
-            // Return strictest policy for this user and profiles that are visible from this user.
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i=0; i<N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
-                        continue;
-                    }
-                    if (length < admin.minimumPasswordSymbols) {
-                        length = admin.minimumPasswordSymbols;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
+                    continue;
+                }
+                if (length < admin.minimumPasswordSymbols) {
+                    length = admin.minimumPasswordSymbols;
                 }
             }
             return length;
@@ -3247,24 +3346,23 @@
     }
 
     @Override
-    public void setPasswordMinimumNonLetter(ComponentName who, int length) {
+    public void setPasswordMinimumNonLetter(ComponentName who, int length, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
             if (ap.minimumPasswordNonLetter != length) {
                 ap.minimumPasswordNonLetter = length;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
     @Override
-    public int getPasswordMinimumNonLetter(ComponentName who, int userHandle) {
+    public int getPasswordMinimumNonLetter(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
@@ -3273,23 +3371,21 @@
             int length = 0;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.minimumPasswordNonLetter : length;
             }
 
-            // Return strictest policy for this user and profiles that are visible from this user.
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i=0; i<N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
-                        continue;
-                    }
-                    if (length < admin.minimumPasswordNonLetter) {
-                        length = admin.minimumPasswordNonLetter;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins =
+                    getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (!isLimitPasswordAllowed(admin, PASSWORD_QUALITY_COMPLEX)) {
+                    continue;
+                }
+                if (length < admin.minimumPasswordNonLetter) {
+                    length = admin.minimumPasswordNonLetter;
                 }
             }
             return length;
@@ -3304,119 +3400,147 @@
         enforceFullCrossUsersPermission(userHandle);
 
         synchronized (this) {
-            int id = getCredentialOwner(userHandle);
-            DevicePolicyData policy = getUserDataUnchecked(id);
-
             // This API can only be called by an active device admin,
             // so try to retrieve it to check that the caller is one.
-            ActiveAdmin admin =
-                    getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
-            ComponentName adminComponentName = admin.info.getComponent();
-            // TODO: Include the Admin sdk level check in LockPatternUtils check.
-            ComponentName who = !isAdminApiLevelMOrBelow(adminComponentName, userHandle)
-                    && isSeparateProfileChallengeEnabled(userHandle)
-                        ? adminComponentName : null;
-            if (policy.mActivePasswordQuality < getPasswordQuality(who, userHandle, parent)
-                    || policy.mActivePasswordLength < getPasswordMinimumLength(null, userHandle)) {
-                return false;
-            }
-            if (policy.mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
-                return true;
-            }
-            return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null, userHandle)
-                && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle)
-                && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle)
-                && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle)
-                && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle)
-                && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle);
+            getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
+            DevicePolicyData policy = getUserDataUnchecked(getCredentialOwner(userHandle, parent));
+            return isActivePasswordSufficientForUserLocked(policy, userHandle, parent);
         }
     }
 
     @Override
-    public int getCurrentFailedPasswordAttempts(int userHandle) {
+    public boolean isProfileActivePasswordSufficientForParent(int userHandle) {
+        if (!mHasFeature) {
+            return true;
+        }
+        enforceFullCrossUsersPermission(userHandle);
+        enforceManagedProfile(userHandle, "call APIs refering to the parent profile");
+
+        synchronized (this) {
+            int targetUser = getProfileParentId(userHandle);
+            DevicePolicyData policy = getUserDataUnchecked(getCredentialOwner(userHandle, false));
+            return isActivePasswordSufficientForUserLocked(policy, targetUser, false);
+        }
+    }
+
+    private boolean isActivePasswordSufficientForUserLocked(
+            DevicePolicyData policy, int userHandle, boolean parent) {
+        if (policy.mActivePasswordQuality < getPasswordQuality(null, userHandle, parent)
+                || policy.mActivePasswordLength < getPasswordMinimumLength(
+                        null, userHandle, parent)) {
+            return false;
+        }
+        if (policy.mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
+            return true;
+        }
+        return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(
+                    null, userHandle, parent)
+                && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(
+                        null, userHandle, parent)
+                && policy.mActivePasswordLetters >= getPasswordMinimumLetters(
+                        null, userHandle, parent)
+                && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(
+                        null, userHandle, parent)
+                && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(
+                        null, userHandle, parent)
+                && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(
+                        null, userHandle, parent);
+    }
+
+    @Override
+    public int getCurrentFailedPasswordAttempts(int userHandle, boolean parent) {
         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);
+            getActiveAdminForCallerLocked(
+                    null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
 
-            int credentialOwnerId = getCredentialOwner(userHandle);
-            DevicePolicyData policy = getUserDataUnchecked(credentialOwnerId);
+            DevicePolicyData policy = getUserDataUnchecked(getCredentialOwner(userHandle, parent));
 
             return policy.mFailedPasswordAttempts;
         }
     }
 
     @Override
-    public void setMaximumFailedPasswordsForWipe(ComponentName who, int num) {
+    public void setMaximumFailedPasswordsForWipe(ComponentName who, int num, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
         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(who,
-                    DeviceAdminInfo.USES_POLICY_WIPE_DATA);
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
+            getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_WIPE_DATA, parent);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
             if (ap.maximumFailedPasswordsForWipe != num) {
                 ap.maximumFailedPasswordsForWipe = num;
-                saveSettingsLocked(userHandle);
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
             }
         }
     }
 
     @Override
-    public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle) {
+    public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
         enforceFullCrossUsersPermission(userHandle);
         synchronized (this) {
-            ActiveAdmin admin = (who != null) ? getActiveAdminUncheckedLocked(who, userHandle)
-                    : getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle);
+            ActiveAdmin admin = (who != null)
+                    ? getActiveAdminUncheckedLocked(who, userHandle, parent)
+                    : getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle, parent);
             return admin != null ? admin.maximumFailedPasswordsForWipe : 0;
         }
     }
 
     @Override
-    public int getProfileWithMinimumFailedPasswordsForWipe(int userHandle) {
+    public int getProfileWithMinimumFailedPasswordsForWipe(int userHandle, boolean parent) {
         if (!mHasFeature) {
             return UserHandle.USER_NULL;
         }
         enforceFullCrossUsersPermission(userHandle);
         synchronized (this) {
-            ActiveAdmin admin = getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle);
+            ActiveAdmin admin = getAdminWithMinimumFailedPasswordsForWipeLocked(
+                    userHandle, parent);
             return admin != null ? admin.getUserHandle().getIdentifier() : UserHandle.USER_NULL;
         }
     }
 
     /**
-     * Returns the admin with the strictest policy on maximum failed passwords for this user and all
-     * profiles that are visible from this user. If the policy for the primary and any other profile
-     * are equal, it returns the admin for the primary profile.
-     * Returns {@code null} if none of them have that policy set.
+     * Returns the admin with the strictest policy on maximum failed passwords for:
+     * <ul>
+     *   <li>this user if it has a separate profile challenge, or
+     *   <li>this user and all profiles that don't have their own challenge otherwise.
+     * </ul>
+     * <p>If the policy for the primary and any other profile are equal, it returns the admin for
+     * the primary profile.
+     * Returns {@code null} if no participating admin has that policy set.
      */
-    private ActiveAdmin getAdminWithMinimumFailedPasswordsForWipeLocked(int userHandle) {
+    private ActiveAdmin getAdminWithMinimumFailedPasswordsForWipeLocked(
+            int userHandle, boolean parent) {
         int count = 0;
         ActiveAdmin strictestAdmin = null;
-        for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
-            DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-            for (ActiveAdmin admin : policy.mAdminList) {
-                if (admin.maximumFailedPasswordsForWipe ==
-                        ActiveAdmin.DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
-                    continue;  // No max number of failed passwords policy set for this profile.
-                }
 
-                // We always favor the primary profile if several profiles have the same value set.
-                if (count == 0 ||
-                        count > admin.maximumFailedPasswordsForWipe ||
-                        (userInfo.isPrimary() && count >= admin.maximumFailedPasswordsForWipe)) {
-                    count = admin.maximumFailedPasswordsForWipe;
-                    strictestAdmin = admin;
-                }
+        // Return the strictest policy across all participating admins.
+        List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
+        final int N = admins.size();
+        for (int i = 0; i < N; i++) {
+            ActiveAdmin admin = admins.get(i);
+            if (admin.maximumFailedPasswordsForWipe ==
+                    ActiveAdmin.DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
+                continue;  // No max number of failed passwords policy set for this profile.
+            }
+
+            // We always favor the primary profile if several profiles have the same value set.
+            int userId = admin.getUserHandle().getIdentifier();
+            if (count == 0 ||
+                    count > admin.maximumFailedPasswordsForWipe ||
+                    (count == admin.maximumFailedPasswordsForWipe &&
+                            mUserManager.getUserInfo(userId).isPrimary())) {
+                count = admin.maximumFailedPasswordsForWipe;
+                strictestAdmin = admin;
             }
         }
         return strictestAdmin;
@@ -3430,14 +3554,9 @@
         final int callingUid = mInjector.binderGetCallingUid();
         final int userHandle = mInjector.userHandleGetCallingUserId();
 
-        long ident = mInjector.binderClearCallingIdentity();
-        try {
-            if (getCredentialOwner(userHandle) != userHandle) {
-                throw new SecurityException("You can not change password for this profile because"
+        if (getCredentialOwner(userHandle, /* parent */ false) != userHandle) {
+            throw new SecurityException("You can not change password for this profile because"
                     + " it shares the password with the owner profile");
-            }
-        } finally {
-            mInjector.binderRestoreCallingIdentity(ident);
         }
 
         String password = passwordOrNull != null ? passwordOrNull : "";
@@ -3481,7 +3600,7 @@
                     }
                 }
             }
-            quality = getPasswordQuality(null, userHandle, false);
+            quality = getPasswordQuality(null, userHandle, /* parent */ false);
             if (quality == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
                 quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
             }
@@ -3497,7 +3616,7 @@
                 }
                 quality = Math.max(realQuality, quality);
             }
-            int length = getPasswordMinimumLength(null, userHandle);
+            int length = getPasswordMinimumLength(null, userHandle, /* parent */ false);
             if (password.length() < length) {
                 Slog.w(LOG_TAG, "resetPassword: password length " + password.length()
                         + " does not meet required length " + length);
@@ -3526,40 +3645,43 @@
                         nonletter++;
                     }
                 }
-                int neededLetters = getPasswordMinimumLetters(null, userHandle);
+                int neededLetters = getPasswordMinimumLetters(null, userHandle, /* parent */ false);
                 if(letters < neededLetters) {
                     Slog.w(LOG_TAG, "resetPassword: number of letters " + letters
                             + " does not meet required number of letters " + neededLetters);
                     return false;
                 }
-                int neededNumbers = getPasswordMinimumNumeric(null, userHandle);
+                int neededNumbers = getPasswordMinimumNumeric(null, userHandle, /* parent */ false);
                 if (numbers < neededNumbers) {
                     Slog.w(LOG_TAG, "resetPassword: number of numerical digits " + numbers
                             + " does not meet required number of numerical digits "
                             + neededNumbers);
                     return false;
                 }
-                int neededLowerCase = getPasswordMinimumLowerCase(null, userHandle);
+                int neededLowerCase = getPasswordMinimumLowerCase(
+                        null, userHandle, /* parent */ false);
                 if (lowercase < neededLowerCase) {
                     Slog.w(LOG_TAG, "resetPassword: number of lowercase letters " + lowercase
                             + " does not meet required number of lowercase letters "
                             + neededLowerCase);
                     return false;
                 }
-                int neededUpperCase = getPasswordMinimumUpperCase(null, userHandle);
+                int neededUpperCase = getPasswordMinimumUpperCase(
+                        null, userHandle, /* parent */ false);
                 if (uppercase < neededUpperCase) {
                     Slog.w(LOG_TAG, "resetPassword: number of uppercase letters " + uppercase
                             + " does not meet required number of uppercase letters "
                             + neededUpperCase);
                     return false;
                 }
-                int neededSymbols = getPasswordMinimumSymbols(null, userHandle);
+                int neededSymbols = getPasswordMinimumSymbols(null, userHandle, /* parent */ false);
                 if (symbols < neededSymbols) {
                     Slog.w(LOG_TAG, "resetPassword: number of special symbols " + symbols
                             + " does not meet required number of special symbols " + neededSymbols);
                     return false;
                 }
-                int neededNonLetter = getPasswordMinimumNonLetter(null, userHandle);
+                int neededNonLetter = getPasswordMinimumNonLetter(
+                        null, userHandle, /* parent */ false);
                 if (nonletter < neededNonLetter) {
                     Slog.w(LOG_TAG, "resetPassword: number of non-letter characters " + nonletter
                             + " does not meet required number of non-letter characters "
@@ -3584,17 +3706,16 @@
 
         // Don't do this with the lock held, because it is going to call
         // back in to the service.
-        ident = mInjector.binderClearCallingIdentity();
+        final long ident = mInjector.binderClearCallingIdentity();
         try {
-            LockPatternUtils utils = mInjector.newLockPatternUtils();
             if (!TextUtils.isEmpty(password)) {
-                utils.saveLockPassword(password, null, quality, userHandle);
+                mLockPatternUtils.saveLockPassword(password, null, quality, userHandle);
             } else {
-                utils.clearLock(userHandle);
+                mLockPatternUtils.clearLock(userHandle);
             }
             boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0;
             if (requireEntry) {
-                utils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
+                mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
                         UserHandle.USER_ALL);
             }
             synchronized (this) {
@@ -3614,7 +3735,7 @@
     private boolean isLockScreenSecureUnchecked(int userId) {
         long ident = mInjector.binderClearCallingIdentity();
         try {
-            return mInjector.newLockPatternUtils().isSecure(userId);
+            return mLockPatternUtils.isSecure(userId);
         } finally {
             mInjector.binderRestoreCallingIdentity(ident);
         }
@@ -3641,50 +3762,69 @@
     }
 
     @Override
-    public void setMaximumTimeToLock(ComponentName who, long timeMs) {
+    public void setMaximumTimeToLock(ComponentName who, long timeMs, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
+        final int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_FORCE_LOCK, parent);
             if (ap.maximumTimeToUnlock != timeMs) {
                 ap.maximumTimeToUnlock = timeMs;
                 saveSettingsLocked(userHandle);
-                updateMaximumTimeToLockLocked(getUserData(userHandle));
+                updateMaximumTimeToLockLocked(userHandle);
             }
         }
     }
 
-    void updateMaximumTimeToLockLocked(DevicePolicyData policy) {
-        long timeMs = getMaximumTimeToLock(null, policy.mUserHandle);
+    void updateMaximumTimeToLockLocked(int userHandle) {
+        // Calculate the min timeout for all profiles - including the ones with a separate
+        // challenge. Ideally if the timeout only affected the profile challenge we'd lock that
+        // challenge only and keep the screen on. However there is no easy way of doing that at the
+        // moment so we set the screen off timeout regardless of whether it affects the parent user
+        // or the profile challenge only.
+        long timeMs = Integer.MAX_VALUE;
+        List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
+        for (UserInfo userInfo : profiles) {
+            DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
+            final int N = policy.mAdminList.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = policy.mAdminList.get(i);
+                if (admin.maximumTimeToUnlock > 0
+                        && timeMs > admin.maximumTimeToUnlock) {
+                    timeMs = admin.maximumTimeToUnlock;
+                }
+            }
+        }
+
+        // We only store the last maximum time to lock on the parent profile. So if calling from a
+        // managed profile, retrieve the policy for the parent.
+        DevicePolicyData policy = getUserDataUnchecked(getProfileParentId(userHandle));
         if (policy.mLastMaximumTimeToLock == timeMs) {
             return;
         }
+        policy.mLastMaximumTimeToLock = timeMs;
 
-        long ident = mInjector.binderClearCallingIdentity();
+        final long ident = mInjector.binderClearCallingIdentity();
         try {
-            if (timeMs <= 0) {
-                timeMs = Integer.MAX_VALUE;
-            } else {
+            if (policy.mLastMaximumTimeToLock != Integer.MAX_VALUE) {
                 // Make sure KEEP_SCREEN_ON is disabled, since that
                 // would allow bypassing of the maximum time to lock.
                 mInjector.settingsGlobalPutInt(Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
             }
 
-            policy.mLastMaximumTimeToLock = timeMs;
             // TODO It can overflow.  Cap it.
             mInjector.getPowerManagerInternal()
-                    .setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
+                    .setMaximumScreenOffTimeoutFromDeviceAdmin((int)policy.mLastMaximumTimeToLock);
         } finally {
             mInjector.binderRestoreCallingIdentity(ident);
         }
     }
 
     @Override
-    public long getMaximumTimeToLock(ComponentName who, int userHandle) {
+    public long getMaximumTimeToLock(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
@@ -3693,23 +3833,21 @@
             long time = 0;
 
             if (who != null) {
-                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                 return admin != null ? admin.maximumTimeToUnlock : time;
             }
 
-            // Return strictest policy for this user and profiles that are visible from this user.
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
-                final int N = policy.mAdminList.size();
-                for (int i=0; i<N; i++) {
-                    ActiveAdmin admin = policy.mAdminList.get(i);
-                    if (time == 0) {
-                        time = admin.maximumTimeToUnlock;
-                    } else if (admin.maximumTimeToUnlock != 0
-                            && time > admin.maximumTimeToUnlock) {
-                        time = admin.maximumTimeToUnlock;
-                    }
+            // Return the strictest policy across all participating admins.
+            List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+                    userHandle, parent);
+            final int N = admins.size();
+            for (int i = 0; i < N; i++) {
+                ActiveAdmin admin = admins.get(i);
+                if (time == 0) {
+                    time = admin.maximumTimeToUnlock;
+                } else if (admin.maximumTimeToUnlock != 0
+                        && time > admin.maximumTimeToUnlock) {
+                    time = admin.maximumTimeToUnlock;
                 }
             }
             return time;
@@ -3717,32 +3855,36 @@
     }
 
     @Override
-    public void lockNow() {
+    public void lockNow(boolean parent) {
         if (!mHasFeature) {
             return;
         }
         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_FORCE_LOCK);
-            lockNowUnchecked();
-        }
-    }
+            getActiveAdminForCallerLocked(
+                    null, DeviceAdminInfo.USES_POLICY_FORCE_LOCK, parent);
 
-    private void lockNowUnchecked() {
-        long ident = mInjector.binderClearCallingIdentity();
-        try {
-            // Power off the display
-            mInjector.powerManagerGoToSleep(SystemClock.uptimeMillis(),
-                    PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
-            // Ensure the device is locked
-            new LockPatternUtils(mContext).requireStrongAuth(
-                    STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW, UserHandle.USER_ALL);
-            mInjector.getIWindowManager().lockNow(null);
-        } catch (RemoteException e) {
-        } finally {
-            mInjector.binderRestoreCallingIdentity(ident);
+            int userToLock = mInjector.userHandleGetCallingUserId();
+
+            // Unless this is a managed profile with work challenge enabled, lock all users.
+            if (parent || !isSeparateProfileChallengeEnabled(userToLock)) {
+                userToLock = UserHandle.USER_ALL;
+            }
+            final long ident = mInjector.binderClearCallingIdentity();
+            try {
+                mLockPatternUtils.requireStrongAuth(
+                        STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW, userToLock);
+                if (userToLock == UserHandle.USER_ALL) {
+                    // Power off the display
+                    mInjector.powerManagerGoToSleep(SystemClock.uptimeMillis(),
+                            PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
+                    mInjector.getIWindowManager().lockNow(null);
+                }
+            } catch (RemoteException e) {
+            } finally {
+                mInjector.binderRestoreCallingIdentity(ident);
+            }
         }
     }
 
@@ -4155,7 +4297,8 @@
             return;
         }
         enforceFullCrossUsersPermission(userHandle);
-        // Managed Profile password can only be changed when per user encryption is present.
+
+        // Managed Profile password can only be changed when it has a separate challenge.
         if (!isSeparateProfileChallengeEnabled(userHandle)) {
             enforceNotManagedProfile(userHandle, "set the active password");
         }
@@ -4180,18 +4323,12 @@
                 policy.mFailedPasswordAttempts = 0;
                 saveSettingsLocked(userHandle);
                 updatePasswordExpirationsLocked(userHandle);
-                setExpirationAlarmCheckLocked(mContext, policy);
+                setExpirationAlarmCheckLocked(mContext, userHandle);
 
                 // Send a broadcast to each profile using this password as its primary unlock.
-                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) {
-                    sendAdminCommandLocked(
-                            DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
-                            DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
-                } else {
-                    sendAdminCommandToSelfAndProfilesLocked(
-                            DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
-                            DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
-                }
+                sendAdminCommandForLockscreenPoliciesLocked(
+                        DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
+                        DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
             }
         } finally {
             mInjector.binderRestoreCallingIdentity(ident);
@@ -4202,33 +4339,35 @@
      * Called any time the device password is updated. Resets all password expiration clocks.
      */
     private void updatePasswordExpirationsLocked(int userHandle) {
-            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
-            for (UserInfo userInfo : profiles) {
-                int profileId = userInfo.id;
-                DevicePolicyData policy = getUserDataUnchecked(profileId);
-                final int N = policy.mAdminList.size();
-                if (N > 0) {
-                    for (int i=0; i<N; i++) {
-                        ActiveAdmin admin = policy.mAdminList.get(i);
-                        if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) {
-                            long timeout = admin.passwordExpirationTimeout;
-                            long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
-                            admin.passwordExpirationDate = expiration;
-                        }
-                    }
-                }
-                saveSettingsLocked(profileId);
+        ArraySet<Integer> affectedUserIds = new ArraySet<Integer>();
+        List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
+                userHandle, /* parent */ false);
+        final int N = admins.size();
+        for (int i = 0; i < N; i++) {
+            ActiveAdmin admin = admins.get(i);
+            if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) {
+                affectedUserIds.add(admin.getUserHandle().getIdentifier());
+                long timeout = admin.passwordExpirationTimeout;
+                long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
+                admin.passwordExpirationDate = expiration;
             }
+        }
+        for (int affectedUserId : affectedUserIds) {
+            saveSettingsLocked(affectedUserId);
+        }
     }
 
     @Override
     public void reportFailedPasswordAttempt(int userHandle) {
         enforceFullCrossUsersPermission(userHandle);
-        enforceNotManagedProfile(userHandle, "report failed password attempt");
+        if (!isSeparateProfileChallengeEnabled(userHandle)) {
+            enforceNotManagedProfile(userHandle,
+                    "report failed password attempt if separate profile challenge is not in place");
+        }
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.BIND_DEVICE_ADMIN, null);
 
-        long ident = mInjector.binderClearCallingIdentity();
+        final long ident = mInjector.binderClearCallingIdentity();
         try {
             boolean wipeData = false;
             int identifier = 0;
@@ -4237,8 +4376,8 @@
                 policy.mFailedPasswordAttempts++;
                 saveSettingsLocked(userHandle);
                 if (mHasFeature) {
-                    ActiveAdmin strictestAdmin =
-                            getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle);
+                    ActiveAdmin strictestAdmin = getAdminWithMinimumFailedPasswordsForWipeLocked(
+                            userHandle, /* parent */ false);
                     int max = strictestAdmin != null
                             ? strictestAdmin.maximumFailedPasswordsForWipe : 0;
                     if (max > 0 && policy.mFailedPasswordAttempts >= max) {
@@ -4248,7 +4387,8 @@
                         wipeData = true;
                         identifier = strictestAdmin.getUserHandle().getIdentifier();
                     }
-                    sendAdminCommandToSelfAndProfilesLocked(
+
+                    sendAdminCommandForLockscreenPoliciesLocked(
                             DeviceAdminReceiver.ACTION_PASSWORD_FAILED,
                             DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
                 }
@@ -4278,7 +4418,7 @@
                     policy.mPasswordOwner = -1;
                     saveSettingsLocked(userHandle);
                     if (mHasFeature) {
-                        sendAdminCommandToSelfAndProfilesLocked(
+                        sendAdminCommandForLockscreenPoliciesLocked(
                                 DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED,
                                 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
                     }
@@ -4669,6 +4809,46 @@
         }
     }
 
+    @Override
+    public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) {
+        if (!mHasFeature) {
+            return;
+        }
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        boolean removeAllUsers = false;
+        synchronized (this) {
+            final ActiveAdmin deviceOwner =
+                    getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+            if (deviceOwner.forceEphemeralUsers != forceEphemeralUsers) {
+                deviceOwner.forceEphemeralUsers = forceEphemeralUsers;
+                saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+                mUserManagerInternal.setForceEphemeralUsers(forceEphemeralUsers);
+                removeAllUsers = forceEphemeralUsers;
+            }
+        }
+        if (removeAllUsers) {
+            long identitity = mInjector.binderClearCallingIdentity();
+            try {
+                mUserManagerInternal.removeAllUsers();
+            } finally {
+                mInjector.binderRestoreCallingIdentity(identitity);
+            }
+        }
+    }
+
+    @Override
+    public boolean getForceEphemeralUsers(ComponentName who) {
+        if (!mHasFeature) {
+            return false;
+        }
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        synchronized (this) {
+            final ActiveAdmin deviceOwner =
+                    getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+            return deviceOwner.forceEphemeralUsers;
+        }
+    }
+
     private void ensureDeviceOwnerManagingSingleUser(ComponentName who) throws SecurityException {
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
@@ -4938,22 +5118,25 @@
         }
     }
 
-    /**
-     * Selectively disable keyguard features.
-     */
     @Override
-    public void setKeyguardDisabledFeatures(ComponentName who, int which) {
+    public void setKeyguardDisabledFeatures(ComponentName who, int which, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        final int userHandle = UserHandle.getCallingUserId();
+        final int userHandle = mInjector.userHandleGetCallingUserId();
         if (isManagedProfile(userHandle)) {
-            which = which & PROFILE_KEYGUARD_FEATURES;
+            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;
+            }
         }
         synchronized (this) {
-            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
+            ActiveAdmin ap = getActiveAdminForCallerLocked(
+                    who, DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES, parent);
             if (ap.disabledKeyguardFeatures != which) {
                 ap.disabledKeyguardFeatures = which;
                 saveSettingsLocked(userHandle);
@@ -4966,50 +5149,43 @@
      * or the aggregate of all active admins if who is null.
      */
     @Override
-    public int getKeyguardDisabledFeatures(ComponentName who, int userHandle) {
+    public int getKeyguardDisabledFeatures(ComponentName who, int userHandle, boolean parent) {
         if (!mHasFeature) {
             return 0;
         }
         enforceFullCrossUsersPermission(userHandle);
-        long ident = mInjector.binderClearCallingIdentity();
+        final long ident = mInjector.binderClearCallingIdentity();
         try {
             synchronized (this) {
                 if (who != null) {
-                    ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+                    ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                     return (admin != null) ? admin.disabledKeyguardFeatures : 0;
                 }
 
-                UserInfo user = mUserManager.getUserInfo(userHandle);
-                final List<UserInfo> profiles;
-                if (user.isManagedProfile()) {
+                final List<ActiveAdmin> admins;
+                if (!parent && isManagedProfile(userHandle)) {
                     // If we are being asked about a managed profile, just return keyguard features
                     // disabled by admins in the profile.
-                    profiles = Collections.singletonList(user);
+                    admins = getUserDataUnchecked(userHandle).mAdminList;
                 } else {
-                    // Otherwise return those set by admins in the user
-                    // and its profiles.
-                    profiles = mUserManager.getProfiles(userHandle);
+                    // Otherwise return those set by admins in the user and its profiles.
+                    admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent);
                 }
 
-                // Determine which keyguard features are disabled by any active admin.
-                int which = 0;
-                for (UserInfo userInfo : profiles) {
-                    DevicePolicyData policy = getUserData(userInfo.id);
-                    final int N = policy.mAdminList.size();
-                    for (int i = 0; i < N; i++) {
-                        ActiveAdmin admin = policy.mAdminList.get(i);
-                        if (userInfo.id == userHandle || !userInfo.isManagedProfile()) {
-                            // If we are being asked explictly about this user
-                            // return all disabled features even if its a managed profile.
-                            which |= admin.disabledKeyguardFeatures;
-                        } else if (!isSeparateProfileChallengeEnabled(
-                                userInfo.id)) {
-                            // Otherwise a managed profile is only allowed to disable
-                            // some features on the parent user, and we only aggregate them if
-                            // it doesn't have its own challenge.
-                            which |= (admin.disabledKeyguardFeatures
-                                    & PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER);
-                        }
+                int which = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
+                final int N = admins.size();
+                for (int i = 0; i < N; i++) {
+                    ActiveAdmin admin = admins.get(i);
+                    int userId = admin.getUserHandle().getIdentifier();
+                    if (userId == userHandle || !isManagedProfile(userHandle)) {
+                        // If we are being asked explicitly about this user
+                        // return all disabled features even if its a managed profile.
+                        which |= admin.disabledKeyguardFeatures;
+                    } else {
+                        // Otherwise a managed profile is only allowed to disable
+                        // some features on the parent user.
+                        which |= (admin.disabledKeyguardFeatures
+                                & PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER);
                     }
                 }
                 return which;
@@ -5203,6 +5379,8 @@
             if (admin != null) {
                 admin.disableCamera = false;
                 admin.userRestrictions = null;
+                admin.forceEphemeralUsers = false;
+                mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers);
             }
 
             clearUserPoliciesLocked(new UserHandle(UserHandle.USER_SYSTEM));
@@ -5270,7 +5448,7 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
             long token = mInjector.binderClearCallingIdentity();
             try {
-                new LockPatternUtils(mContext).setDeviceOwnerInfo(info);
+                mLockPatternUtils.setDeviceOwnerInfo(info);
             } finally {
                 mInjector.binderRestoreCallingIdentity(token);
             }
@@ -5280,7 +5458,7 @@
 
     @Override
     public String getDeviceOwnerLockScreenInfo() {
-        return new LockPatternUtils(mContext).getDeviceOwnerInfo();
+        return mLockPatternUtils.getDeviceOwnerInfo();
     }
 
     private void clearUserPoliciesLocked(UserHandle userHandle) {
@@ -5291,6 +5469,7 @@
         policy.mDelegatedCertInstallerPackage = null;
         policy.mApplicationRestrictionsManagingPackage = null;
         policy.mStatusBarDisabled = false;
+        policy.mUserProvisioningState = DevicePolicyManager.STATE_USER_UNMANAGED;
         saveSettingsLocked(userId);
 
         final long ident = mInjector.binderClearCallingIdentity();
@@ -5318,6 +5497,98 @@
     }
 
     @Override
+    public int getUserProvisioningState() {
+        if (!mHasFeature) {
+            return DevicePolicyManager.STATE_USER_UNMANAGED;
+        }
+        int userHandle = mInjector.userHandleGetCallingUserId();
+        return getUserProvisioningState(userHandle);
+    }
+
+    private int getUserProvisioningState(int userHandle) {
+        return getUserData(userHandle).mUserProvisioningState;
+    }
+
+    @Override
+    public void setUserProvisioningState(int newState, int userHandle) {
+        if (!mHasFeature) {
+            return;
+        }
+
+        if (userHandle != mOwners.getDeviceOwnerUserId() && !mOwners.hasProfileOwner(userHandle)
+                && getManagedUserId(userHandle) == -1) {
+            // No managed device, user or profile, so setting provisioning state makes no sense.
+            throw new IllegalStateException("Not allowed to change provisioning state unless a "
+                      + "device or profile owner is set.");
+        }
+
+        synchronized (this) {
+            boolean transitionCheckNeeded = true;
+
+            // Calling identity/permission checks.
+            final int callingUid = mInjector.binderGetCallingUid();
+            if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) {
+                // ADB shell can only move directly from un-managed to finalized as part of directly
+                // setting profile-owner or device-owner.
+                if (getUserProvisioningState(userHandle) !=
+                        DevicePolicyManager.STATE_USER_UNMANAGED
+                        || newState != DevicePolicyManager.STATE_USER_SETUP_FINALIZED) {
+                    throw new IllegalStateException("Not allowed to change provisioning state "
+                            + "unless current provisioning state is unmanaged, and new state is "
+                            + "finalized.");
+                }
+                transitionCheckNeeded = false;
+            } else {
+                // For all other cases, caller must have MANAGE_PROFILE_AND_DEVICE_OWNERS.
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null);
+            }
+
+            final DevicePolicyData policyData = getUserData(userHandle);
+            if (transitionCheckNeeded) {
+                // Optional state transition check for non-ADB case.
+                checkUserProvisioningStateTransition(policyData.mUserProvisioningState, newState);
+            }
+            policyData.mUserProvisioningState = newState;
+            saveSettingsLocked(userHandle);
+        }
+    }
+
+    private void checkUserProvisioningStateTransition(int currentState, int newState) {
+        // Valid transitions for normal use-cases.
+        switch (currentState) {
+            case DevicePolicyManager.STATE_USER_UNMANAGED:
+                // Can move to any state from unmanaged (except itself as an edge case)..
+                if (newState != DevicePolicyManager.STATE_USER_UNMANAGED) {
+                    return;
+                }
+                break;
+            case DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE:
+            case DevicePolicyManager.STATE_USER_SETUP_COMPLETE:
+                // Can only move to finalized from these states.
+                if (newState == DevicePolicyManager.STATE_USER_SETUP_FINALIZED) {
+                    return;
+                }
+                break;
+            case DevicePolicyManager.STATE_USER_PROFILE_COMPLETE:
+                // Current user has a managed-profile, but current user is not managed, so
+                // rather than moving to finalized state, go back to unmanaged once
+                // profile provisioning is complete.
+                if (newState == DevicePolicyManager.STATE_USER_UNMANAGED) {
+                    return;
+                }
+                break;
+            case DevicePolicyManager.STATE_USER_SETUP_FINALIZED:
+                // Cannot transition out of finalized.
+                break;
+        }
+
+        // Didn't meet any of the accepted state transition checks above, throw appropriate error.
+        throw new IllegalStateException("Cannot move to user provisioning state [" + newState + "] "
+                + "from state [" + currentState + "]");
+    }
+
+    @Override
     public void setProfileEnabled(ComponentName who) {
         if (!mHasFeature) {
             return;
@@ -5557,15 +5828,37 @@
         }
     }
 
-    private void enforceNotManagedProfile(int userHandle, String message) {
-        if(isManagedProfile(userHandle)) {
-            throw new SecurityException("You can not " + message + " for a managed profile. ");
+    private void enforceManagedProfile(int userHandle, String message) {
+        if(!isManagedProfile(userHandle)) {
+            throw new SecurityException("You can not " + message + " outside a managed profile.");
         }
     }
 
-    private int getCredentialOwner(int userHandle) {
-        long ident = mInjector.binderClearCallingIdentity();
+    private void enforceNotManagedProfile(int userHandle, String message) {
+        if(isManagedProfile(userHandle)) {
+            throw new SecurityException("You can not " + message + " for a managed profile.");
+        }
+    }
+
+    private int getProfileParentId(int userHandle) {
+        final long ident = mInjector.binderClearCallingIdentity();
         try {
+            UserInfo parentUser = mUserManager.getProfileParent(userHandle);
+            return parentUser != null ? parentUser.id : userHandle;
+        } finally {
+            mInjector.binderRestoreCallingIdentity(ident);
+        }
+    }
+
+    private int getCredentialOwner(int userHandle, boolean parent) {
+        final long ident = mInjector.binderClearCallingIdentity();
+        try {
+            if (parent) {
+                UserInfo parentProfile = mUserManager.getProfileParent(userHandle);
+                if (parentProfile != null) {
+                    userHandle = parentProfile.id;
+                }
+            }
             return mUserManager.getCredentialOwnerProfile(userHandle);
         } finally {
             mInjector.binderRestoreCallingIdentity(ident);
@@ -5614,7 +5907,8 @@
             for (int u = 0; u < userCount; u++) {
                 DevicePolicyData policy = getUserData(mUserData.keyAt(u));
                 pw.println();
-                pw.println("  Enabled Device Admins (User " + policy.mUserHandle + "):");
+                pw.println("  Enabled Device Admins (User " + policy.mUserHandle
+                        + ", provisioningState: " + policy.mUserProvisioningState + "):");
                 final int N = policy.mAdminList.size();
                 for (int i=0; i<N; i++) {
                     ActiveAdmin ap = policy.mAdminList.get(i);
@@ -6261,6 +6555,94 @@
         }
     }
 
+    private void sendAdminEnabledBroadcastLocked(int userHandle) {
+        DevicePolicyData policyData = getUserData(userHandle);
+        if (policyData.mAdminBroadcastPending) {
+            // Send the initialization data to profile owner and delete the data
+            ActiveAdmin admin = getProfileOwnerAdminLocked(userHandle);
+            if (admin != null) {
+                PersistableBundle initBundle = policyData.mInitBundle;
+                sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED,
+                        initBundle == null ? null : new Bundle(initBundle), null);
+            }
+            policyData.mInitBundle = null;
+            policyData.mAdminBroadcastPending = false;
+            saveSettingsLocked(userHandle);
+        }
+    }
+
+    @Override
+    public UserHandle createAndManageUser(ComponentName admin, String name,
+            ComponentName profileOwner, PersistableBundle adminExtras, int flags) {
+        Preconditions.checkNotNull(admin, "admin is null");
+        Preconditions.checkNotNull(profileOwner, "profileOwner is null");
+        if (!admin.getPackageName().equals(profileOwner.getPackageName())) {
+            throw new IllegalArgumentException("profileOwner " + profileOwner + " and admin "
+                    + admin + " are not in the same package");
+        }
+        // Create user.
+        UserHandle user = null;
+        synchronized (this) {
+            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+
+            final long id = mInjector.binderClearCallingIdentity();
+            try {
+                int userInfoFlags = 0;
+                if ((flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) {
+                    userInfoFlags |= UserInfo.FLAG_EPHEMERAL;
+                }
+                UserInfo userInfo = mUserManager.createUser(name, userInfoFlags);
+                if (userInfo != null) {
+                    user = userInfo.getUserHandle();
+                }
+            } finally {
+                mInjector.binderRestoreCallingIdentity(id);
+            }
+        }
+        if (user == null) {
+            return null;
+        }
+        // Set admin.
+        final long id = mInjector.binderClearCallingIdentity();
+        try {
+            final String adminPkg = admin.getPackageName();
+
+            final int userHandle = user.getIdentifier();
+            try {
+                // Install the profile owner if not present.
+                if (!mIPackageManager.isPackageAvailable(adminPkg, userHandle)) {
+                    mIPackageManager.installExistingPackageAsUser(adminPkg, userHandle);
+                }
+            } catch (RemoteException e) {
+                Slog.e(LOG_TAG, "Failed to make remote calls for createAndManageUser, "
+                        + "removing created user", e);
+                mUserManager.removeUser(user.getIdentifier());
+                return null;
+            }
+
+            setActiveAdmin(profileOwner, true, userHandle);
+            // User is not started yet, the broadcast by setActiveAdmin will not be received.
+            // So we store adminExtras for broadcasting when the user starts for first time.
+            synchronized(this) {
+                DevicePolicyData policyData = getUserData(userHandle);
+                policyData.mInitBundle = adminExtras;
+                policyData.mAdminBroadcastPending = true;
+                saveSettingsLocked(userHandle);
+            }
+            final String ownerName = getProfileOwnerName(Process.myUserHandle().getIdentifier());
+            setProfileOwner(profileOwner, ownerName, userHandle);
+
+            if ((flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0) {
+                Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.USER_SETUP_COMPLETE, 1, userHandle);
+            }
+
+            return user;
+        } finally {
+            mInjector.binderRestoreCallingIdentity(id);
+        }
+    }
+
     @Override
     public boolean removeUser(ComponentName who, UserHandle userHandle) {
         Preconditions.checkNotNull(who, "ComponentName is null");
@@ -6502,15 +6884,8 @@
                             + userId);
                 }
 
-                UserManager um = UserManager.get(mContext);
-                UserInfo primaryUser = um.getProfileParent(userId);
-
-                // Call did not come from a managed profile
-                if (primaryUser == null) {
-                    primaryUser = um.getUserInfo(userId);
-                }
-
-                if (!isSystemApp(mIPackageManager, packageName, primaryUser.id)) {
+                int parentUserId = getProfileParentId(userId);
+                if (!isSystemApp(mIPackageManager, packageName, parentUserId)) {
                     throw new IllegalArgumentException("Only system apps can be enabled this way.");
                 }
 
@@ -6538,19 +6913,12 @@
             long id = mInjector.binderClearCallingIdentity();
 
             try {
-                UserManager um = UserManager.get(mContext);
-                UserInfo primaryUser = um.getProfileParent(userId);
-
-                // Call did not come from a managed profile.
-                if (primaryUser == null) {
-                    primaryUser = um.getUserInfo(userId);
-                }
-
+                int parentUserId = getProfileParentId(userId);
                 List<ResolveInfo> activitiesToEnable = mIPackageManager.queryIntentActivities(
                         intent,
                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                         0, // no flags
-                        primaryUser.id);
+                        parentUserId);
 
                 if (VERBOSE_LOG) {
                     Slog.d(LOG_TAG, "Enabling system activities: " + activitiesToEnable);
@@ -6560,7 +6928,7 @@
                     for (ResolveInfo info : activitiesToEnable) {
                         if (info.activityInfo != null) {
                             String packageName = info.activityInfo.packageName;
-                            if (isSystemApp(mIPackageManager, packageName, primaryUser.id)) {
+                            if (isSystemApp(mIPackageManager, packageName, parentUserId)) {
                                 numberOfAppsInstalled++;
                                 mIPackageManager.installExistingPackageAsUser(packageName, userId);
                             } else {
@@ -6757,9 +7125,9 @@
 
     @Override
     public void startManagedQuickContact(String actualLookupKey, long actualContactId,
-            long actualDirectoryId, Intent originalIntent) {
-        final Intent intent = QuickContact.rebuildManagedQuickContactsIntent(
-                actualLookupKey, actualContactId, actualDirectoryId, originalIntent);
+            boolean isContactIdIgnored, long actualDirectoryId, Intent originalIntent) {
+        final Intent intent = QuickContact.rebuildManagedQuickContactsIntent(actualLookupKey,
+                actualContactId, isContactIdIgnored, actualDirectoryId, originalIntent);
         final int callingUserId = UserHandle.getCallingUserId();
 
         final long ident = mInjector.binderClearCallingIdentity();
@@ -6964,7 +7332,8 @@
 
             if (Settings.Global.STAY_ON_WHILE_PLUGGED_IN.equals(setting)) {
                 // ignore if it contradicts an existing policy
-                long timeMs = getMaximumTimeToLock(who, UserHandle.getCallingUserId());
+                long timeMs = getMaximumTimeToLock(
+                        who, mInjector.userHandleGetCallingUserId(), /* parent */ false);
                 if (timeMs > 0 && timeMs < Integer.MAX_VALUE) {
                     return;
                 }
@@ -6987,7 +7356,7 @@
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
 
-            if (isDeviceOwner(who, mInjector.userHandleGetCallingUserId())) {
+            if (isDeviceOwner(who, callingUserId)) {
                 if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)) {
                     throw new SecurityException(String.format(
                             "Permission denial: Device owners cannot update %1$s", setting));
@@ -7060,15 +7429,14 @@
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
         }
         final int userId = UserHandle.getCallingUserId();
-        LockPatternUtils utils = new LockPatternUtils(mContext);
 
         long ident = mInjector.binderClearCallingIdentity();
         try {
             // disallow disabling the keyguard if a password is currently set
-            if (disabled && utils.isSecure(userId)) {
+            if (disabled && mLockPatternUtils.isSecure(userId)) {
                 return false;
             }
-            utils.setLockScreenDisabled(disabled, userId);
+            mLockPatternUtils.setLockScreenDisabled(disabled, userId);
         } finally {
             mInjector.binderRestoreCallingIdentity(ident);
         }
@@ -7201,7 +7569,6 @@
 
         @Override
         public boolean isActiveAdminWithPolicy(int uid, int reqPolicy) {
-            final int userId = UserHandle.getUserId(uid);
             synchronized(DevicePolicyManagerService.this) {
                 return getActiveAdminWithPolicyForUidLocked(null, reqPolicy, uid) != null;
             }
@@ -7721,6 +8088,7 @@
         if (!mHasFeature || !isManagedProfile(userHandle)) {
             return ActiveAdmin.DEF_ORGANIZATION_COLOR;
         }
+        Preconditions.checkNotNull(who, "ComponentName is null");
         synchronized (this) {
             ActiveAdmin admin = getActiveAdminForCallerLocked(who,
                     DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -7741,4 +8109,48 @@
                     : ActiveAdmin.DEF_ORGANIZATION_COLOR;
         }
     }
+
+    @Override
+    public void setAffiliationIds(ComponentName admin, List<String> ids) {
+        final Set<String> affiliationIds = new ArraySet<String>(ids);
+        final int callingUserId = mInjector.userHandleGetCallingUserId();
+
+        synchronized (this) {
+            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+            getUserData(callingUserId).mAffiliationIds = affiliationIds;
+            saveSettingsLocked(callingUserId);
+            if (callingUserId != UserHandle.USER_SYSTEM && isDeviceOwner(admin, callingUserId)) {
+                // Affiliation ids specified by the device owner are additionally stored in
+                // UserHandle.USER_SYSTEM's DevicePolicyData.
+                getUserData(UserHandle.USER_SYSTEM).mAffiliationIds = affiliationIds;
+                saveSettingsLocked(UserHandle.USER_SYSTEM);
+            }
+        }
+    }
+
+    @Override
+    public boolean isAffiliatedUser() {
+        final int callingUserId = mInjector.userHandleGetCallingUserId();
+
+        synchronized (this) {
+            if (mOwners.getDeviceOwnerUserId() == callingUserId) {
+                // The user that the DO is installed on is always affiliated.
+                return true;
+            }
+            final ComponentName profileOwner = getProfileOwner(callingUserId);
+            if (profileOwner == null
+                    || !profileOwner.getPackageName().equals(mOwners.getDeviceOwnerPackageName())) {
+                return false;
+            }
+            final Set<String> userAffiliationIds = getUserData(callingUserId).mAffiliationIds;
+            final Set<String> deviceAffiliationIds =
+                    getUserData(UserHandle.USER_SYSTEM).mAffiliationIds;
+            for (String id : userAffiliationIds) {
+                if (deviceAffiliationIds.contains(id)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c186a12..361c251 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -84,6 +84,7 @@
 import com.android.server.power.PowerManagerService;
 import com.android.server.power.ShutdownThread;
 import com.android.server.restrictions.RestrictionsManagerService;
+import com.android.server.soundtrigger.SoundTriggerService;
 import com.android.server.statusbar.StatusBarManagerService;
 import com.android.server.storage.DeviceStorageMonitorService;
 import com.android.server.telecom.TelecomLoaderService;
@@ -959,6 +960,8 @@
 
             mSystemServiceManager.startService(JobSchedulerService.class);
 
+            mSystemServiceManager.startService(SoundTriggerService.class);
+
             if (!disableNonCoreServices) {
                 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BACKUP)) {
                     mSystemServiceManager.startService(BACKUP_MANAGER_SERVICE_CLASS);
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 5abb6e7..e6f4177 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -20,6 +20,7 @@
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.content.ComponentName;
@@ -47,11 +48,11 @@
 import android.print.PrinterId;
 import android.printservice.PrintServiceInfo;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.util.SparseArray;
 
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.Preconditions;
 import com.android.server.SystemService;
 
 import java.io.FileDescriptor;
@@ -108,6 +109,10 @@
         @Override
         public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
                 PrintAttributes attributes, String packageName, int appId, int userId) {
+            printJobName = Preconditions.checkStringNotEmpty(printJobName);
+            adapter = Preconditions.checkNotNull(adapter);
+            packageName = Preconditions.checkStringNotEmpty(packageName);
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final int resolvedAppId;
             final UserState userState;
@@ -153,6 +158,10 @@
 
         @Override
         public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) {
+            if (printJobId == null) {
+                return null;
+            }
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final int resolvedAppId;
             final UserState userState;
@@ -174,6 +183,8 @@
 
         @Override
         public Icon getCustomPrinterIcon(PrinterId printerId, int userId) {
+            printerId = Preconditions.checkNotNull(printerId);
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -193,6 +204,10 @@
 
         @Override
         public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) {
+            if (printJobId == null) {
+                return;
+            }
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final int resolvedAppId;
             final UserState userState;
@@ -214,6 +229,10 @@
 
         @Override
         public void restartPrintJob(PrintJobId printJobId, int appId, int userId) {
+            if (printJobId == null) {
+                return;
+            }
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final int resolvedAppId;
             final UserState userState;
@@ -279,6 +298,8 @@
         @Override
         public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
                 int userId) {
+            observer = Preconditions.checkNotNull(observer);
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -299,6 +320,8 @@
         @Override
         public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
                 int userId) {
+            observer = Preconditions.checkNotNull(observer);
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -319,6 +342,12 @@
         @Override
         public void startPrinterDiscovery(IPrinterDiscoveryObserver observer,
                 List<PrinterId> priorityList, int userId) {
+            observer = Preconditions.checkNotNull(observer);
+            if (priorityList != null) {
+                priorityList = Preconditions.checkCollectionElementsNotNull(priorityList,
+                        "PrinterId");
+            }
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -338,6 +367,8 @@
 
         @Override
         public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) {
+            observer = Preconditions.checkNotNull(observer);
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -357,6 +388,8 @@
 
         @Override
         public void validatePrinters(List<PrinterId> printerIds, int userId) {
+            printerIds = Preconditions.checkCollectionElementsNotNull(printerIds, "PrinterId");
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -376,6 +409,8 @@
 
         @Override
         public void startPrinterStateTracking(PrinterId printerId, int userId) {
+            printerId = Preconditions.checkNotNull(printerId);
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -395,6 +430,8 @@
 
         @Override
         public void stopPrinterStateTracking(PrinterId printerId, int userId) {
+            printerId = Preconditions.checkNotNull(printerId);
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -415,6 +452,8 @@
         @Override
         public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener,
                 int appId, int userId) throws RemoteException {
+            listener = Preconditions.checkNotNull(listener);
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final int resolvedAppId;
             final UserState userState;
@@ -437,6 +476,8 @@
         @Override
         public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener,
                 int userId) {
+            listener = Preconditions.checkNotNull(listener);
+
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -456,6 +497,9 @@
 
         @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            fd = Preconditions.checkNotNull(fd);
+            pw = Preconditions.checkNotNull(pw);
+
             if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
                     != PackageManager.PERMISSION_GRANTED) {
                 pw.println("Permission Denial: can't dump PrintManager from from pid="
@@ -707,10 +751,8 @@
             return userId;
         }
 
-        private String resolveCallingPackageNameEnforcingSecurity(String packageName) {
-            if (TextUtils.isEmpty(packageName)) {
-                return null;
-            }
+        private @NonNull String resolveCallingPackageNameEnforcingSecurity(
+                @NonNull String packageName) {
             String[] packages = mContext.getPackageManager().getPackagesForUid(
                     Binder.getCallingUid());
             final int packageCount = packages.length;
@@ -719,7 +761,7 @@
                     return packageName;
                 }
             }
-            return null;
+            throw new IllegalArgumentException("packageName has to belong to the caller");
         }
 
         private int getCurrentUserId () {
diff --git a/services/print/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java
index 5ee4066..9b99c67 100644
--- a/services/print/java/com/android/server/print/RemotePrintService.java
+++ b/services/print/java/com/android/server/print/RemotePrintService.java
@@ -409,7 +409,7 @@
         }
     }
 
-    public void startPrinterStateTracking(PrinterId printerId) {
+    public void startPrinterStateTracking(@NonNull PrinterId printerId) {
         mHandler.obtainMessage(MyHandler.MSG_START_PRINTER_STATE_TRACKING,
                 printerId).sendToTarget();
     }
@@ -420,7 +420,7 @@
      * @param printerId the id of the printer the icon should be loaded for
      * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
      */
-    public void requestCustomPrinterIcon(PrinterId printerId) {
+    public void requestCustomPrinterIcon(@NonNull PrinterId printerId) {
         try {
             if (isBound()) {
                 mPrintService.requestCustomPrinterIcon(printerId);
@@ -430,7 +430,7 @@
         }
     }
 
-    private void handleStartPrinterStateTracking(final PrinterId printerId) {
+    private void handleStartPrinterStateTracking(final @NonNull PrinterId printerId) {
         throwIfDestroyed();
         // Take a note we are tracking the printer.
         if (mTrackedPrinterList == null) {
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 78edc4d..fcf2fc8 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -20,6 +20,7 @@
 import static android.content.pm.PackageManager.GET_SERVICES;
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.ComponentName;
@@ -176,8 +177,8 @@
     }
 
     @SuppressWarnings("deprecation")
-    public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
-            PrintAttributes attributes, String packageName, int appId) {
+    public Bundle print(@NonNull String printJobName, @NonNull IPrintDocumentAdapter adapter,
+            @Nullable PrintAttributes attributes, @NonNull String packageName, int appId) {
         // Create print job place holder.
         final PrintJobInfo printJob = new PrintJobInfo();
         printJob.setId(new PrintJobId());
@@ -267,7 +268,7 @@
         return new ArrayList<PrintJobInfo>(result.values());
     }
 
-    public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId) {
+    public PrintJobInfo getPrintJobInfo(@NonNull PrintJobId printJobId, int appId) {
         PrintJobInfo printJob = mPrintJobForAppCache.getPrintJob(printJobId, appId);
         if (printJob == null) {
             printJob = mSpooler.getPrintJobInfo(printJobId, appId);
@@ -290,7 +291,7 @@
      *         not yet available
      * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
      */
-    public Icon getCustomPrinterIcon(PrinterId printerId) {
+    public @Nullable Icon getCustomPrinterIcon(@NonNull PrinterId printerId) {
         Icon icon = mSpooler.getCustomPrinterIcon(printerId);
 
         if (icon == null) {
@@ -303,7 +304,7 @@
         return icon;
     }
 
-    public void cancelPrintJob(PrintJobId printJobId, int appId) {
+    public void cancelPrintJob(@NonNull PrintJobId printJobId, int appId) {
         PrintJobInfo printJobInfo = mSpooler.getPrintJobInfo(printJobId, appId);
         if (printJobInfo == null) {
             return;
@@ -313,15 +314,19 @@
         mSpooler.setPrintJobCancelling(printJobId, true);
 
         if (printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
-            ComponentName printServiceName = printJobInfo.getPrinterId().getServiceName();
-            RemotePrintService printService = null;
-            synchronized (mLock) {
-                printService = mActiveServices.get(printServiceName);
+            PrinterId printerId = printJobInfo.getPrinterId();
+
+            if (printerId != null) {
+                ComponentName printServiceName = printerId.getServiceName();
+                RemotePrintService printService = null;
+                synchronized (mLock) {
+                    printService = mActiveServices.get(printServiceName);
+                }
+                if (printService == null) {
+                    return;
+                }
+                printService.onRequestCancelPrintJob(printJobInfo);
             }
-            if (printService == null) {
-                return;
-            }
-            printService.onRequestCancelPrintJob(printJobInfo);
         } else {
             // If the print job is failed we do not need cooperation
             // from the print service.
@@ -329,7 +334,7 @@
         }
     }
 
-    public void restartPrintJob(PrintJobId printJobId, int appId) {
+    public void restartPrintJob(@NonNull PrintJobId printJobId, int appId) {
         PrintJobInfo printJobInfo = getPrintJobInfo(printJobId, appId);
         if (printJobInfo == null || printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
             return;
@@ -363,7 +368,7 @@
         }
     }
 
-    public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer) {
+    public void createPrinterDiscoverySession(@NonNull IPrinterDiscoveryObserver observer) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
 
@@ -386,7 +391,7 @@
         }
     }
 
-    public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer) {
+    public void destroyPrinterDiscoverySession(@NonNull IPrinterDiscoveryObserver observer) {
         synchronized (mLock) {
             // Already destroyed - nothing to do.
             if (mPrinterDiscoverySession == null) {
@@ -397,8 +402,8 @@
         }
     }
 
-    public void startPrinterDiscovery(IPrinterDiscoveryObserver observer,
-            List<PrinterId> printerIds) {
+    public void startPrinterDiscovery(@NonNull IPrinterDiscoveryObserver observer,
+            @Nullable List<PrinterId> printerIds) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
             // No services - nothing to do.
@@ -415,7 +420,7 @@
         }
     }
 
-    public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer) {
+    public void stopPrinterDiscovery(@NonNull IPrinterDiscoveryObserver observer) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
             // No services - nothing to do.
@@ -431,7 +436,7 @@
         }
     }
 
-    public void validatePrinters(List<PrinterId> printerIds) {
+    public void validatePrinters(@NonNull List<PrinterId> printerIds) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
             // No services - nothing to do.
@@ -447,7 +452,7 @@
         }
     }
 
-    public void startPrinterStateTracking(PrinterId printerId) {
+    public void startPrinterStateTracking(@NonNull PrinterId printerId) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
             // No services - nothing to do.
@@ -479,7 +484,7 @@
         }
     }
 
-    public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener,
+    public void addPrintJobStateChangeListener(@NonNull IPrintJobStateChangeListener listener,
             int appId) throws RemoteException {
         synchronized (mLock) {
             throwIfDestroyedLocked();
@@ -497,7 +502,7 @@
         }
     }
 
-    public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener) {
+    public void removePrintJobStateChangeListener(@NonNull IPrintJobStateChangeListener listener) {
         synchronized (mLock) {
             throwIfDestroyedLocked();
             if (mPrintJobStateChangeListenerRecords == null) {
@@ -613,7 +618,7 @@
         mDestroyed = true;
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String prefix) {
+    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String prefix) {
         pw.append(prefix).append("user state ").append(String.valueOf(mUserId)).append(":");
         pw.println();
 
@@ -991,10 +996,10 @@
     }
 
     private abstract class PrintJobStateChangeListenerRecord implements DeathRecipient {
-        final IPrintJobStateChangeListener listener;
+        @NonNull final IPrintJobStateChangeListener listener;
         final int appId;
 
-        public PrintJobStateChangeListenerRecord(IPrintJobStateChangeListener listener,
+        public PrintJobStateChangeListenerRecord(@NonNull IPrintJobStateChangeListener listener,
                 int appId) throws RemoteException {
             this.listener = listener;
             this.appId = appId;
@@ -1043,7 +1048,7 @@
                     .sendToTarget();
         }
 
-        public void addObserverLocked(IPrinterDiscoveryObserver observer) {
+        public void addObserverLocked(@NonNull IPrinterDiscoveryObserver observer) {
             // Add the observer.
             mDiscoveryObservers.register(observer);
 
@@ -1058,7 +1063,7 @@
             }
         }
 
-        public void removeObserverLocked(IPrinterDiscoveryObserver observer) {
+        public void removeObserverLocked(@NonNull IPrinterDiscoveryObserver observer) {
             // Remove the observer.
             mDiscoveryObservers.unregister(observer);
             // No one else observing - then kill it.
@@ -1067,8 +1072,8 @@
             }
         }
 
-        public final void startPrinterDiscoveryLocked(IPrinterDiscoveryObserver observer,
-                List<PrinterId> priorityList) {
+        public final void startPrinterDiscoveryLocked(@NonNull IPrinterDiscoveryObserver observer,
+                @Nullable List<PrinterId> priorityList) {
             if (mIsDestroyed) {
                 Log.w(LOG_TAG, "Not starting dicovery - session destroyed");
                 return;
@@ -1101,7 +1106,7 @@
                     .sendToTarget();
         }
 
-        public final void stopPrinterDiscoveryLocked(IPrinterDiscoveryObserver observer) {
+        public final void stopPrinterDiscoveryLocked(@NonNull IPrinterDiscoveryObserver observer) {
             if (mIsDestroyed) {
                 Log.w(LOG_TAG, "Not stopping dicovery - session destroyed");
                 return;
@@ -1121,7 +1126,7 @@
                     .sendToTarget();
         }
 
-        public void validatePrintersLocked(List<PrinterId> printerIds) {
+        public void validatePrintersLocked(@NonNull List<PrinterId> printerIds) {
             if (mIsDestroyed) {
                 Log.w(LOG_TAG, "Not validating pritners - session destroyed");
                 return;
@@ -1135,13 +1140,15 @@
                 ComponentName serviceName = null;
                 while (iterator.hasNext()) {
                     PrinterId printerId = iterator.next();
-                    if (updateList.isEmpty()) {
-                        updateList.add(printerId);
-                        serviceName = printerId.getServiceName();
-                        iterator.remove();
-                    } else if (printerId.getServiceName().equals(serviceName)) {
-                        updateList.add(printerId);
-                        iterator.remove();
+                    if (printerId != null) {
+                        if (updateList.isEmpty()) {
+                            updateList.add(printerId);
+                            serviceName = printerId.getServiceName();
+                            iterator.remove();
+                        } else if (printerId.getServiceName().equals(serviceName)) {
+                            updateList.add(printerId);
+                            iterator.remove();
+                        }
                     }
                 }
                 // Schedule a notification of the service.
@@ -1157,7 +1164,7 @@
             }
         }
 
-        public final void startPrinterStateTrackingLocked(PrinterId printerId) {
+        public final void startPrinterStateTrackingLocked(@NonNull PrinterId printerId) {
             if (mIsDestroyed) {
                 Log.w(LOG_TAG, "Not starting printer state tracking - session destroyed");
                 return;
@@ -1500,8 +1507,8 @@
             service.validatePrinters(printerIds);
         }
 
-        private void handleStartPrinterStateTracking(RemotePrintService service,
-                PrinterId printerId) {
+        private void handleStartPrinterStateTracking(@NonNull RemotePrintService service,
+                @NonNull PrinterId printerId) {
             service.startPrinterStateTracking(printerId);
         }
 
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 672058b..87569b7 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -15,9 +15,6 @@
  */
 package com.android.server.devicepolicy;
 
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-
 import android.Manifest.permission;
 import android.app.Activity;
 import android.app.admin.DeviceAdminReceiver;
@@ -27,23 +24,30 @@
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
 import android.net.wifi.WifiInfo;
-import android.os.Build;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.ArraySet;
 import android.util.Pair;
 
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+
 import org.mockito.ArgumentCaptor;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
@@ -62,13 +66,18 @@
  *
  m FrameworksServicesTests &&
  adb install \
-   -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
+   -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
  adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest \
    -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
 
  (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
  */
+@SmallTest
 public class DevicePolicyManagerTest extends DpmTestBase {
+    private static final List<String> OWNER_SETUP_PERMISSIONS = Arrays.asList(
+            permission.MANAGE_DEVICE_ADMINS, permission.MANAGE_PROFILE_AND_DEVICE_OWNERS,
+            permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL);
+
     private DpmMockContext mContext;
     public DevicePolicyManager dpm;
     public DevicePolicyManagerServiceTestable dpms;
@@ -1476,4 +1485,221 @@
             assertNull(dpm.getLongSupportMessage(admin1));
         }
     }
+
+    /**
+     * Test for:
+     * {@link DevicePolicyManager#setAffiliationIds}
+     * {@link DevicePolicyManager#isAffiliatedUser}
+     */
+    public void testUserAffiliation() throws Exception {
+        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
+
+        // Check that the system user is unaffiliated.
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        assertFalse(dpm.isAffiliatedUser());
+
+        // Set a device owner on the system user. Check that the system user becomes affiliated.
+        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
+        dpm.setActiveAdmin(admin1, /* replace =*/ false);
+        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
+        assertTrue(dpm.isAffiliatedUser());
+
+        // Install a profile owner whose package name matches the device owner on a test user. Check
+        // that the test user is unaffiliated.
+        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+        setAsProfileOwner(admin2);
+        assertFalse(dpm.isAffiliatedUser());
+
+        // Have the profile owner specify a set of affiliation ids. Check that the test user remains
+        // unaffiliated.
+        final Set<String> userAffiliationIds = new ArraySet<>();
+        userAffiliationIds.add("red");
+        userAffiliationIds.add("green");
+        userAffiliationIds.add("blue");
+        dpm.setAffiliationIds(admin2, userAffiliationIds);
+        assertFalse(dpm.isAffiliatedUser());
+
+        // Have the device owner specify a set of affiliation ids that do not intersect with those
+        // specified by the profile owner. Check that the test user remains unaffiliated.
+        final Set<String> deviceAffiliationIds = new ArraySet<>();
+        deviceAffiliationIds.add("cyan");
+        deviceAffiliationIds.add("yellow");
+        deviceAffiliationIds.add("magenta");
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        dpm.setAffiliationIds(admin1, deviceAffiliationIds);
+        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+        assertFalse(dpm.isAffiliatedUser());
+
+        // Have the profile owner specify a set of affiliation ids that intersect with those
+        // specified by the device owner. Check that the test user becomes affiliated.
+        userAffiliationIds.add("yellow");
+        dpm.setAffiliationIds(admin2, userAffiliationIds);
+        assertTrue(dpm.isAffiliatedUser());
+
+        // Change the profile owner to one whose package name does not match the device owner. Check
+        // that the test user is not affiliated anymore.
+        dpm.clearProfileOwner(admin2);
+        final ComponentName admin = new ComponentName("test", "test");
+        markPackageAsInstalled(admin.getPackageName(), null, DpmMockContext.CALLER_USER_HANDLE);
+        assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
+        assertFalse(dpm.isAffiliatedUser());
+
+        // Check that the system user remains affiliated.
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        assertTrue(dpm.isAffiliatedUser());
+    }
+
+    public void testGetUserProvisioningState_defaultResult() {
+        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
+    }
+
+    public void testSetUserProvisioningState_permission() throws Exception {
+        setupProfileOwner();
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
+    }
+
+    public void testSetUserProvisioningState_unprivileged() throws Exception {
+        setupProfileOwner();
+        try {
+            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                    DpmMockContext.CALLER_USER_HANDLE);
+            fail("Expected SecurityException");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    public void testSetUserProvisioningState_noManagement() {
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+        try {
+            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                    DpmMockContext.CALLER_USER_HANDLE);
+            fail("IllegalStateException expected");
+        } catch (IllegalStateException e) {
+            MoreAsserts.assertContainsRegex("change provisioning state unless a .* owner is set",
+                    e.getMessage());
+        }
+        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
+    }
+
+    public void testSetUserProvisioningState_deviceOwnerFromSetupWizard() throws Exception {
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        setupDeviceOwner();
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
+                DevicePolicyManager.STATE_USER_SETUP_COMPLETE,
+                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
+    }
+
+    public void testSetUserProvisioningState_deviceOwnerFromSetupWizardAlternative()
+            throws Exception {
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        setupDeviceOwner();
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
+                DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
+                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
+    }
+
+    public void testSetUserProvisioningState_deviceOwnerWithoutSetupWizard() throws Exception {
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        setupDeviceOwner();
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
+                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
+    }
+
+    public void testSetUserProvisioningState_managedProfileFromSetupWizard_primaryUser()
+            throws Exception {
+        setupProfileOwner();
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                DevicePolicyManager.STATE_USER_PROFILE_COMPLETE,
+                DevicePolicyManager.STATE_USER_UNMANAGED);
+    }
+
+    public void testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile()
+            throws Exception {
+        setupProfileOwner();
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                DevicePolicyManager.STATE_USER_SETUP_COMPLETE,
+                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
+    }
+
+    public void testSetUserProvisioningState_managedProfileWithoutSetupWizard() throws Exception {
+        setupProfileOwner();
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
+    }
+
+    public void testSetUserProvisioningState_illegalTransitionOutOfFinalized1() throws Exception {
+        setupProfileOwner();
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        try {
+            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                    DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
+                    DevicePolicyManager.STATE_USER_UNMANAGED);
+            fail("Expected IllegalStateException");
+        } catch (IllegalStateException e) {
+            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
+                    e.getMessage());
+        }
+    }
+
+    public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState()
+            throws Exception {
+        setupProfileOwner();
+        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+        try {
+            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
+                    DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
+                    DevicePolicyManager.STATE_USER_SETUP_COMPLETE);
+            fail("Expected IllegalStateException");
+        } catch (IllegalStateException e) {
+            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
+                    e.getMessage());
+        }
+    }
+
+    private void exerciseUserProvisioningTransitions(int userId, int... states) {
+        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
+        for (int state : states) {
+            dpm.setUserProvisioningState(state, userId);
+            assertEquals(state, dpm.getUserProvisioningState());
+        }
+    }
+
+    private void setupProfileOwner() throws Exception {
+        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
+
+        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
+        dpm.setActiveAdmin(admin1, false);
+        assertTrue(dpm.setProfileOwner(admin1, null, DpmMockContext.CALLER_USER_HANDLE));
+
+        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
+    }
+
+    private void setupDeviceOwner() throws Exception {
+        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
+
+        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
+        dpm.setActiveAdmin(admin1, false);
+        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
+
+        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTestable.java
index b80f3bf..3da61d6 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTestable.java
@@ -26,7 +26,7 @@
 
     public DevicePolicyManagerTestable(DpmMockContext context,
             DevicePolicyManagerServiceTestable dpms) {
-        super(context, dpms);
+        super(context, dpms, /* parentInstance = */ false);
         this.dpms = dpms;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
index c557ab7..3dc1a9a 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
@@ -65,6 +65,22 @@
         return mMockContext;
     }
 
+    protected void markPackageAsInstalled(String packageName, ApplicationInfo ai, int userId)
+            throws Exception {
+        final PackageInfo pi = DpmTestUtils.cloneParcelable(
+                mRealTestContext.getPackageManager().getPackageInfo(
+                        mRealTestContext.getPackageName(), 0));
+        assertTrue(pi.applicationInfo.flags != 0);
+
+        if (ai != null) {
+            pi.applicationInfo = ai;
+        }
+
+        doReturn(pi).when(mMockContext.ipackageManager).getPackageInfo(
+                eq(packageName),
+                eq(0),
+                eq(userId));
+    }
 
     protected void setUpPackageManagerForAdmin(ComponentName admin, int packageUid)
             throws Exception {
@@ -124,17 +140,6 @@
                 eq(UserHandle.getUserId(packageUid)));
 
         // Set up getPackageInfo().
-
-        final PackageInfo pi = DpmTestUtils.cloneParcelable(
-                mRealTestContext.getPackageManager().getPackageInfo(
-                        admin.getPackageName(), 0));
-        assertTrue(pi.applicationInfo.flags != 0);
-
-        pi.applicationInfo = ai;
-
-        doReturn(pi).when(mMockContext.ipackageManager).getPackageInfo(
-                eq(admin.getPackageName()),
-                eq(0),
-                eq(UserHandle.getUserId(packageUid)));
+        markPackageAsInstalled(admin.getPackageName(), ai, UserHandle.getUserId(packageUid));
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
index 2640889..31182fc 100644
--- a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -155,16 +155,12 @@
 
     @SmallTest
     public void testTopicImportanceExtractor() throws Exception {
-        mHelper.setTopicImportance("package", 0, new Notification.Topic("A", "a"),
-                IMPORTANCE_MAX);
+        mHelper.setImportance("package", 0, new Notification.Topic("A", "a"), IMPORTANCE_MAX);
         // There is no B. There never was a b. Moving on...
-        mHelper.setTopicImportance("package", 0, new Notification.Topic("C", "c"),
-                IMPORTANCE_HIGH);
-        mHelper.setTopicImportance("package", 0, new Notification.Topic("D", "d"),
-                IMPORTANCE_LOW);
+        mHelper.setImportance("package", 0, new Notification.Topic("C", "c"), IMPORTANCE_HIGH);
+        mHelper.setImportance("package", 0, new Notification.Topic("D", "d"), IMPORTANCE_LOW);
         // watch out: different package.
-        mHelper.setTopicImportance("package2", 0, new Notification.Topic("E", "e"),
-                IMPORTANCE_NONE);
+        mHelper.setImportance("package2", 0, new Notification.Topic("E", "e"), IMPORTANCE_NONE);
 
         TopicImportanceExtractor validator = mHelper.findExtractor(TopicImportanceExtractor.class);
         validator.process(mRecordGroupGSortA);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 0ca4bd8..87c5ba0 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -17,6 +17,7 @@
 package com.android.server.usage;
 
 import android.app.usage.TimeSparseArray;
+import android.app.usage.UsageStats;
 import android.app.usage.UsageStatsManager;
 import android.os.Build;
 import android.util.AtomicFile;
@@ -25,6 +26,10 @@
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
@@ -39,6 +44,14 @@
 class UsageStatsDatabase {
     private static final int CURRENT_VERSION = 3;
 
+    // Current version of the backup schema
+    static final int BACKUP_STATE_VERSION = 1;
+
+    // Key under which the payload blob is stored
+    // same as UsageStatsBackupHelper.KEY_USAGE_STATS
+    static final String KEY_USAGE_STATS = "usage_stats";
+
+
     private static final String TAG = "UsageStatsDatabase";
     private static final boolean DEBUG = UsageStatsService.DEBUG;
     private static final String BAK_SUFFIX = ".bak";
@@ -539,4 +552,186 @@
             stats.lastTimeSaved = f.getLastModifiedTime();
         }
     }
+
+
+    /* Backup/Restore Code */
+    protected byte[] getBackupPayload(String key){
+        synchronized (mLock) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            if (KEY_USAGE_STATS.equals(key)) {
+                prune(System.currentTimeMillis());
+                DataOutputStream out = new DataOutputStream(baos);
+                try {
+                    out.writeInt(BACKUP_STATE_VERSION);
+
+                    out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].size());
+                    for(int i = 0; i<mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].size(); i++){
+                        writeIntervalStatsToStream(out, mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].valueAt(i));
+                    }
+
+                    out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].size());
+                    for(int i = 0; i<mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].size(); i++){
+                        writeIntervalStatsToStream(out, mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].valueAt(i));
+                    }
+
+                    out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].size());
+                    for(int i = 0; i<mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].size(); i++){
+                        writeIntervalStatsToStream(out, mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].valueAt(i));
+                    }
+
+                    out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].size());
+                    for(int i = 0; i<mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].size(); i++){
+                        writeIntervalStatsToStream(out, mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].valueAt(i));
+                    }
+                    if (DEBUG) Slog.i(TAG, "Written " + baos.size() + " bytes of data");
+                } catch (IOException ioe){
+                    Slog.d(TAG, "Failed to write data to output stream", ioe);
+                    baos.reset();
+                }
+            }
+            return baos.toByteArray();
+        }
+
+    }
+
+    protected void applyRestoredPayload(String key, byte[] payload){
+        synchronized (mLock) {
+            if (KEY_USAGE_STATS.equals(key)) {
+                // Read stats files for the current device configs
+                IntervalStats dailyConfigSource = getLatestUsageStats(UsageStatsManager.INTERVAL_DAILY);
+                IntervalStats weeklyConfigSource = getLatestUsageStats(UsageStatsManager.INTERVAL_WEEKLY);
+                IntervalStats monthlyConfigSource = getLatestUsageStats(UsageStatsManager.INTERVAL_MONTHLY);
+                IntervalStats yearlyConfigSource = getLatestUsageStats(UsageStatsManager.INTERVAL_YEARLY);
+
+                // Delete all stats files
+                for(int i = 0; i<mIntervalDirs.length; i++){
+                    deleteDirectoryContents(mIntervalDirs[i]);
+                }
+                try {
+                    DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload));
+                    int stateVersion = in.readInt();
+
+                    int fileCount = in.readInt();
+                    for(int i = 0; i<fileCount; i++){
+                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in));
+                        stats = mergeStats(stats, dailyConfigSource);
+                        putUsageStats(UsageStatsManager.INTERVAL_DAILY, stats);
+                    }
+
+                    fileCount = in.readInt();
+                    for(int i = 0; i<fileCount; i++){
+                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in));
+                        stats = mergeStats(stats, weeklyConfigSource);
+                        putUsageStats(UsageStatsManager.INTERVAL_WEEKLY, stats);
+                    }
+
+                    fileCount = in.readInt();
+                    for(int i = 0; i<fileCount; i++){
+                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in));
+                        stats = mergeStats(stats, monthlyConfigSource);
+                        putUsageStats(UsageStatsManager.INTERVAL_MONTHLY, stats);
+                    }
+
+                    fileCount = in.readInt();
+                    for(int i = 0; i<fileCount; i++){
+                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in));
+                        stats = mergeStats(stats, yearlyConfigSource);
+                        putUsageStats(UsageStatsManager.INTERVAL_YEARLY, stats);
+                    }
+                    if (DEBUG) Slog.i(TAG, "Completed Restoring UsageStats");
+                } catch (IOException ioe){
+                    Slog.d(TAG, "Failed to read data from input stream", ioe);
+                }
+                finally {
+                    indexFilesLocked();
+                }
+            }
+        }
+    }
+
+    /**
+     * Get the Configuration Statistics from the current device statistics and merge them
+     * with the backed up usage statistics.
+     */
+    private IntervalStats mergeStats(IntervalStats beingRestored, IntervalStats onDevice) {
+        beingRestored.activeConfiguration = onDevice.activeConfiguration;
+        beingRestored.configurations.putAll(onDevice.configurations);
+        beingRestored.events = onDevice.events;
+        return beingRestored;
+    }
+
+    private void writeIntervalStatsToStream(DataOutputStream out, AtomicFile statsFile) throws IOException{
+        IntervalStats stats = new IntervalStats();
+        try {
+            UsageStatsXml.read(statsFile, stats);
+        } catch (IOException e) {
+            Slog.e(TAG, "Failed to read usage stats file", e);
+            out.writeInt(0);
+            return;
+        }
+        sanitizeIntervalStatsForBackup(stats);
+        byte[] data = serializeIntervalStats(stats);
+        out.writeInt(data.length);
+        out.write(data);
+    }
+
+    private static byte[] getIntervalStatsBytes(DataInputStream in) throws IOException {
+        int length = in.readInt();
+        byte[] buffer = new byte[length];
+        in.read(buffer, 0, length);
+        return buffer;
+    }
+
+    private static void sanitizeIntervalStatsForBackup(IntervalStats stats) {
+        if (stats == null) return;
+        stats.activeConfiguration = null;
+        stats.configurations.clear();
+        if (stats.events != null) stats.events.clear();
+    }
+
+    private static byte[] serializeIntervalStats(IntervalStats stats) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream out = new DataOutputStream(baos);
+        try {
+            out.writeLong(stats.beginTime);
+            UsageStatsXml.write(out, stats);
+        } catch (IOException ioe) {
+            Slog.d(TAG, "Serializing IntervalStats Failed", ioe);
+            baos.reset();
+        }
+        return baos.toByteArray();
+    }
+
+    private static IntervalStats deserializeIntervalStats(byte[] data) {
+        ByteArrayInputStream bais = new ByteArrayInputStream(data);
+        DataInputStream in = new DataInputStream(bais);
+        IntervalStats stats = new IntervalStats();
+        try {
+            stats.beginTime = in.readLong();
+            UsageStatsXml.read(in, stats);
+        } catch (IOException ioe) {
+            Slog.d(TAG, "DeSerializing IntervalStats Failed", ioe);
+            stats = null;
+        }
+        return stats;
+    }
+
+    private static void deleteDirectoryContents(File directory){
+        File[] files = directory.listFiles();
+        for (File file : files) {
+            deleteDirectory(file);
+        }
+    }
+
+    private static void deleteDirectory(File directory) {
+        File[] files = directory.listFiles();
+        for (File file : files) {
+            if (!file.isDirectory()) {
+                file.delete();
+            } else {
+                deleteDirectory(file);
+            }
+        }
+        directory.delete();
+    }
 }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index f2949bf4..81031da 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -1310,6 +1310,8 @@
             }
             UsageStatsService.this.dump(args, pw);
         }
+
+
     }
 
     /**
@@ -1416,5 +1418,26 @@
                 AppIdleStateChangeListener listener) {
             UsageStatsService.this.removeListener(listener);
         }
+
+        @Override
+        public byte[] getBackupPayload(int user, String key) {
+            // Check to ensure that only user 0's data is b/r for now
+            if (user == UserHandle.USER_SYSTEM) {
+                final UserUsageStatsService userStats =
+                        getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked());
+                return userStats.getBackupPayload(key);
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        public void applyRestoredPayload(int user, String key, byte[] payload) {
+            if (user == UserHandle.USER_SYSTEM) {
+                final UserUsageStatsService userStats =
+                        getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked());
+                userStats.applyRestoredPayload(key, payload);
+            }
+        }
     }
 }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXml.java b/services/usage/java/com/android/server/usage/UsageStatsXml.java
index 543f361..e7db741 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXml.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXml.java
@@ -87,7 +87,7 @@
         }
     }
 
-    private static void read(InputStream in, IntervalStats statsOut) throws IOException {
+    static void read(InputStream in, IntervalStats statsOut) throws IOException {
         XmlPullParser parser = Xml.newPullParser();
         try {
             parser.setInput(in, "utf-8");
@@ -113,7 +113,7 @@
         }
     }
 
-    private static void write(OutputStream out, IntervalStats stats) throws IOException {
+    static void write(OutputStream out, IntervalStats stats) throws IOException {
         FastXmlSerializer xml = new FastXmlSerializer();
         xml.setOutput(out, "utf-8");
         xml.startDocument("utf-8", true);
@@ -126,4 +126,4 @@
         xml.endTag(null, USAGESTATS_TAG);
         xml.endDocument();
     }
-}
+}
\ No newline at end of file
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 224faf4..aa2cf77 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -741,4 +741,12 @@
                 return "UNKNOWN";
         }
     }
+
+    byte[] getBackupPayload(String key){
+        return mDatabase.getBackupPayload(key);
+    }
+
+    void applyRestoredPayload(String key, byte[] payload){
+        mDatabase.applyRestoredPayload(key, payload);
+    }
 }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java
new file mode 100644
index 0000000..18a5d59
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java
@@ -0,0 +1,144 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.soundtrigger;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import java.util.Locale;
+import java.util.UUID;
+
+/**
+ * Helper to manage the database of the sound models that have been registered on the device.
+ *
+ * @hide
+ */
+public class SoundTriggerDbHelper extends SQLiteOpenHelper {
+    static final String TAG = "SoundTriggerDbHelper";
+    static final boolean DBG = false;
+
+    private static final String NAME = "st_sound_model.db";
+    private static final int VERSION = 1;
+
+    // Sound trigger-based sound models.
+    public static interface GenericSoundModelContract {
+        public static final String TABLE = "st_sound_model";
+        public static final String KEY_MODEL_UUID = "model_uuid";
+        public static final String KEY_VENDOR_UUID = "vendor_uuid";
+        public static final String KEY_DATA = "data";
+    }
+
+
+    // Table Create Statement for the sound trigger table
+    private static final String CREATE_TABLE_ST_SOUND_MODEL = "CREATE TABLE "
+            + GenericSoundModelContract.TABLE + "("
+            + GenericSoundModelContract.KEY_MODEL_UUID + " TEXT PRIMARY KEY,"
+            + GenericSoundModelContract.KEY_DATA + " BLOB" + " )";
+
+
+    public SoundTriggerDbHelper(Context context) {
+        super(context, NAME, null, VERSION);
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        // creating required tables
+        db.execSQL(CREATE_TABLE_ST_SOUND_MODEL);
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        // TODO: For now, drop older tables and recreate new ones.
+        db.execSQL("DROP TABLE IF EXISTS " + GenericSoundModelContract.TABLE);
+        onCreate(db);
+    }
+
+    /**
+     * Updates the given sound trigger model, adds it, if it doesn't already exist.
+     *
+     */
+    public boolean updateGenericSoundModel(GenericSoundModel soundModel) {
+        synchronized(this) {
+            SQLiteDatabase db = getWritableDatabase();
+            ContentValues values = new ContentValues();
+            values.put(GenericSoundModelContract.KEY_MODEL_UUID, soundModel.uuid.toString());
+            values.put(GenericSoundModelContract.KEY_VENDOR_UUID, soundModel.vendorUuid.toString());
+            values.put(GenericSoundModelContract.KEY_DATA, soundModel.data);
+
+            try {
+                return db.insertWithOnConflict(GenericSoundModelContract.TABLE, null, values,
+                        SQLiteDatabase.CONFLICT_REPLACE) != -1;
+            } finally {
+                db.close();
+            }
+
+        }
+    }
+
+    public GenericSoundModel getGenericSoundModel(UUID model_uuid) {
+        synchronized(this) {
+
+            // Find the corresponding sound model ID for the keyphrase.
+            String selectQuery = "SELECT  * FROM " + GenericSoundModelContract.TABLE
+                    + " WHERE " + GenericSoundModelContract.KEY_MODEL_UUID + "= '" +
+                    model_uuid + "'";
+            SQLiteDatabase db = getReadableDatabase();
+            Cursor c = db.rawQuery(selectQuery, null);
+            try {
+                if (c.moveToFirst()) {
+                    do {
+                        byte[] data = c.getBlob(c.getColumnIndex(
+                                GenericSoundModelContract.KEY_DATA));
+                        String vendor_uuid = c.getString(
+                                c.getColumnIndex(GenericSoundModelContract.KEY_VENDOR_UUID));
+                        return new GenericSoundModel(model_uuid, UUID.fromString(vendor_uuid),
+                                data);
+                    } while (c.moveToNext());
+                }
+            } finally {
+                c.close();
+                db.close();
+            }
+        }
+        return null;
+    }
+
+    public boolean deleteGenericSoundModel(UUID model_uuid) {
+        synchronized(this) {
+            GenericSoundModel soundModel = getGenericSoundModel(model_uuid);
+            if (soundModel == null) {
+                return false;
+            }
+            // Delete all sound models for the given keyphrase and specified user.
+            SQLiteDatabase db = getWritableDatabase();
+            String soundModelClause = GenericSoundModelContract.KEY_MODEL_UUID
+                    + "='" + soundModel.uuid.toString() + "'";
+            try {
+                return db.delete(GenericSoundModelContract.TABLE, soundModelClause, null) != 0;
+            } finally {
+                db.close();
+            }
+        }
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
similarity index 99%
rename from services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
rename to services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 31d859f..597f915ec 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.voiceinteraction;
+package com.android.server.soundtrigger;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java
new file mode 100644
index 0000000..0a06bfa
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.soundtrigger;
+
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
+import android.hardware.soundtrigger.SoundTrigger.SoundModelEvent;
+import android.hardware.soundtrigger.SoundTriggerModule;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Provides a local service for managing voice-related recoginition models. This is primarily used
+ * by the {@link VoiceInteractionManagerService}.
+ */
+public abstract class SoundTriggerInternal {
+    /**
+     * Return codes for {@link #startRecognition(int, KeyphraseSoundModel,
+     *      IRecognitionStatusCallback, RecognitionConfig)},
+     * {@link #stopRecognition(int, IRecognitionStatusCallback)}
+     */
+    public static final int STATUS_ERROR = SoundTrigger.STATUS_ERROR;
+    public static final int STATUS_OK = SoundTrigger.STATUS_OK;
+
+    /** The {@link ModuleProperties} for the system, or null if none exists. */
+    private ModuleProperties moduleProperties;
+
+    /**
+     * Starts recognition for the given keyphraseId.
+     *
+     * @param keyphraseId The identifier of the keyphrase for which
+     *        the recognition is to be started.
+     * @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}.
+     */
+    public abstract int startRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
+            IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig);
+
+    /**
+     * Stops recognition for the given {@link Keyphrase} if a recognition is
+     * currently active.
+     *
+     * @param keyphraseId The identifier of the keyphrase for which
+     *        the recognition is to be stopped.
+     * @param listener The listener for the recognition events related to the given keyphrase.
+     *
+     * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
+     */
+    public abstract int stopRecognition(int keyphraseId, IRecognitionStatusCallback listener);
+
+    /**
+     * Stops all recognitions active currently and clears the internal state.
+     */
+    public abstract void stopAllRecognitions();
+
+    public ModuleProperties getModuleProperties() {
+        return moduleProperties;
+    }
+
+    public abstract void dump(FileDescriptor fd, PrintWriter pw, String[] args);
+}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
new file mode 100644
index 0000000..5e8fe9e
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.soundtrigger;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.Manifest;
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.SystemService;
+import com.android.internal.app.ISoundTriggerService;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.UUID;
+
+/**
+ * A single SystemService to manage all sound/voice-based sound models on the DSP.
+ * This services provides apis to manage sound trigger-based sound models via
+ * the ISoundTriggerService interface. This class also publishes a local interface encapsulating
+ * the functionality provided by {@link SoundTriggerHelper} for use by
+ * {@link VoiceInteractionManagerService}.
+ *
+ * @hide
+ */
+public class SoundTriggerService extends SystemService {
+    static final String TAG = "SoundTriggerService";
+    static final boolean DEBUG = false;
+
+    final Context mContext;
+    private final SoundTriggerServiceStub mServiceStub;
+    private final LocalSoundTriggerService mLocalSoundTriggerService;
+    private SoundTriggerDbHelper mDbHelper;
+
+    public SoundTriggerService(Context context) {
+        super(context);
+        mContext = context;
+        mServiceStub = new SoundTriggerServiceStub();
+        mLocalSoundTriggerService = new LocalSoundTriggerService(context);
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.SOUND_TRIGGER_SERVICE, mServiceStub);
+        publishLocalService(SoundTriggerInternal.class, mLocalSoundTriggerService);
+    }
+
+    @Override
+    public void onBootPhase(int phase) {
+        if (PHASE_SYSTEM_SERVICES_READY == phase) {
+            mLocalSoundTriggerService.initSoundTriggerHelper();
+        } else if (PHASE_THIRD_PARTY_APPS_CAN_START == phase) {
+            mDbHelper = new SoundTriggerDbHelper(mContext);
+        }
+    }
+
+    @Override
+    public void onStartUser(int userHandle) {
+    }
+
+    @Override
+    public void onSwitchUser(int userHandle) {
+    }
+
+    class SoundTriggerServiceStub extends ISoundTriggerService.Stub {
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            try {
+                return super.onTransact(code, data, reply, flags);
+            } catch (RuntimeException e) {
+                // The activity manager only throws security exceptions, so let's
+                // log all others.
+                if (!(e instanceof SecurityException)) {
+                    Slog.wtf(TAG, "SoundTriggerService Crash", e);
+                }
+                throw e;
+            }
+        }
+
+        @Override
+        public void startRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (DEBUG) {
+                Slog.i(TAG, "startRecognition(): Uuid : " + parcelUuid);
+            }
+        }
+
+        @Override
+        public void stopRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (DEBUG) {
+                Slog.i(TAG, "stopRecognition(): Uuid : " + parcelUuid);
+            }
+        }
+
+        @Override
+        public SoundTrigger.GenericSoundModel getSoundModel(ParcelUuid soundModelId) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            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.");
+            }
+            return model;
+        }
+
+        @Override
+        public void updateSoundModel(SoundTrigger.GenericSoundModel soundModel) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (DEBUG) {
+                Slog.i(TAG, "updateSoundModel(): model = " + soundModel);
+            }
+            mDbHelper.updateGenericSoundModel(soundModel);
+        }
+
+        @Override
+        public void deleteSoundModel(ParcelUuid soundModelId) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (DEBUG) {
+                Slog.i(TAG, "deleteSoundModel(): id = " + soundModelId);
+            }
+            mDbHelper.deleteGenericSoundModel(soundModelId.getUuid());
+        }
+    }
+
+    public final class LocalSoundTriggerService extends SoundTriggerInternal {
+        private final Context mContext;
+        private SoundTriggerHelper mSoundTriggerHelper;
+
+        LocalSoundTriggerService(Context context) {
+            mContext = context;
+        }
+
+        void initSoundTriggerHelper() {
+            if (mSoundTriggerHelper == null) {
+                mSoundTriggerHelper = new SoundTriggerHelper(mContext);
+            }
+        }
+
+        @Override
+        public int startRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
+                IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig) {
+            return mSoundTriggerHelper.startRecognition(keyphraseId, soundModel, listener,
+                    recognitionConfig);
+        }
+
+        @Override
+        public int stopRecognition(int keyphraseId, IRecognitionStatusCallback listener) {
+            return mSoundTriggerHelper.stopRecognition(keyphraseId, listener);
+        }
+
+        @Override
+        public void stopAllRecognitions() {
+            mSoundTriggerHelper.stopAllRecognitions();
+        }
+
+        @Override
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            mSoundTriggerHelper.dump(fd, pw, args);
+        }
+    }
+
+    private void enforceCallingPermission(String permission) {
+        if (mContext.checkCallingOrSelfPermission(permission)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Caller does not hold the permission " + permission);
+        }
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 8fee91f..4a54643 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -18,6 +18,8 @@
 
 import android.Manifest;
 import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -45,6 +47,7 @@
 import android.provider.Settings;
 import android.service.voice.IVoiceInteractionService;
 import android.service.voice.IVoiceInteractionSession;
+import android.service.voice.VoiceInteractionManagerInternal;
 import android.service.voice.VoiceInteractionService;
 import android.service.voice.VoiceInteractionServiceInfo;
 import android.service.voice.VoiceInteractionSession;
@@ -59,6 +62,7 @@
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
 import com.android.server.LocalServices;
+import com.android.server.soundtrigger.SoundTriggerInternal;
 import com.android.server.SystemService;
 import com.android.server.UiThread;
 
@@ -71,20 +75,21 @@
  */
 public class VoiceInteractionManagerService extends SystemService {
     static final String TAG = "VoiceInteractionManagerService";
-    static final boolean DEBUG = false;
+    static final boolean DEBUG = true;
 
     final Context mContext;
     final ContentResolver mResolver;
     final DatabaseHelper mDbHelper;
-    final SoundTriggerHelper mSoundTriggerHelper;
+    final ActivityManagerInternal mAmInternal;
+    SoundTriggerInternal mSoundTriggerInternal;
 
     public VoiceInteractionManagerService(Context context) {
         super(context);
         mContext = context;
         mResolver = context.getContentResolver();
         mDbHelper = new DatabaseHelper(context);
-        mSoundTriggerHelper = new SoundTriggerHelper(context);
         mServiceStub = new VoiceInteractionManagerServiceStub();
+        mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
 
         PackageManagerInternal packageManagerInternal = LocalServices.getService(
                 PackageManagerInternal.class);
@@ -105,11 +110,14 @@
     @Override
     public void onStart() {
         publishBinderService(Context.VOICE_INTERACTION_MANAGER_SERVICE, mServiceStub);
+        publishLocalService(VoiceInteractionManagerInternal.class, new LocalService());
     }
 
     @Override
     public void onBootPhase(int phase) {
-        if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+        if (PHASE_SYSTEM_SERVICES_READY == phase) {
+            mSoundTriggerInternal = LocalServices.getService(SoundTriggerInternal.class);
+        } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
             mServiceStub.systemRunning(isSafeMode());
         }
     }
@@ -124,6 +132,31 @@
         mServiceStub.switchUser(userHandle);
     }
 
+    class LocalService extends VoiceInteractionManagerInternal {
+        @Override
+        public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
+            if (DEBUG) {
+                Slog.i(TAG, "startLocalVoiceInteraction " + callingActivity);
+            }
+            VoiceInteractionManagerService.this.mServiceStub.startLocalVoiceInteraction(
+                    callingActivity, options);
+        }
+
+        @Override
+        public boolean supportsLocalVoiceInteraction() {
+            return VoiceInteractionManagerService.this.mServiceStub.supportsLocalVoiceInteraction();
+        }
+
+        @Override
+        public void stopLocalVoiceInteraction(IBinder callingActivity) {
+            if (DEBUG) {
+                Slog.i(TAG, "stopLocalVoiceInteraction " + callingActivity);
+            }
+            VoiceInteractionManagerService.this.mServiceStub.stopLocalVoiceInteraction(
+                    callingActivity);
+        }
+    }
+
     // implementation entry point and binder service
     private final VoiceInteractionManagerServiceStub mServiceStub;
 
@@ -139,6 +172,49 @@
             mEnableService = shouldEnableService(mContext.getResources());
         }
 
+        // TODO: VI Make sure the caller is the current user or profile
+        void startLocalVoiceInteraction(final IBinder token, Bundle options) {
+            if (mImpl == null) return;
+
+            final long caller = Binder.clearCallingIdentity();
+            try {
+                mImpl.showSessionLocked(options,
+                        VoiceInteractionSession.SHOW_SOURCE_ACTIVITY,
+                        new IVoiceInteractionSessionShowCallback.Stub() {
+                            @Override
+                            public void onFailed() {
+                            }
+
+                            @Override
+                            public void onShown() {
+                                mAmInternal.onLocalVoiceInteractionStarted(token,
+                                        mImpl.mActiveSession.mSession,
+                                        mImpl.mActiveSession.mInteractor);
+                            }
+                        },
+                        token);
+            } finally {
+                Binder.restoreCallingIdentity(caller);
+            }
+        }
+
+        public void stopLocalVoiceInteraction(IBinder callingActivity) {
+            if (mImpl == null) return;
+
+            final long caller = Binder.clearCallingIdentity();
+            try {
+                mImpl.finishLocked(callingActivity, true);
+            } finally {
+                Binder.restoreCallingIdentity(caller);
+            }
+        }
+
+        public boolean supportsLocalVoiceInteraction() {
+            if (mImpl == null) return false;
+
+            return mImpl.supportsLocalVoiceInteraction();
+        }
+
         @Override
         public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
                 throws RemoteException {
@@ -306,7 +382,7 @@
 
                 if (force || mImpl == null || mImpl.mUser != mCurUser
                         || !mImpl.mComponent.equals(serviceComponent)) {
-                    mSoundTriggerHelper.stopAllRecognitions();
+                    mSoundTriggerInternal.stopAllRecognitions();
                     if (mImpl != null) {
                         mImpl.shutdownLocked();
                     }
@@ -568,7 +644,7 @@
                 }
                 final long caller = Binder.clearCallingIdentity();
                 try {
-                    mImpl.finishLocked(token);
+                    mImpl.finishLocked(token, false);
                 } finally {
                     Binder.restoreCallingIdentity(caller);
                 }
@@ -662,9 +738,9 @@
                             mImpl.notifySoundModelsChangedLocked();
                         }
                     }
-                    return SoundTriggerHelper.STATUS_OK;
+                    return SoundTriggerInternal.STATUS_OK;
                 } else {
-                    return SoundTriggerHelper.STATUS_ERROR;
+                    return SoundTriggerInternal.STATUS_ERROR;
                 }
             } finally {
                 Binder.restoreCallingIdentity(caller);
@@ -685,7 +761,7 @@
             boolean deleted = false;
             try {
                 deleted = mDbHelper.deleteKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
-                return deleted ? SoundTriggerHelper.STATUS_OK : SoundTriggerHelper.STATUS_ERROR;
+                return deleted ? SoundTriggerInternal.STATUS_OK : SoundTriggerInternal.STATUS_ERROR;
             } finally {
                 if (deleted) {
                     synchronized (this) {
@@ -738,7 +814,7 @@
 
                 final long caller = Binder.clearCallingIdentity();
                 try {
-                    return mSoundTriggerHelper.moduleProperties;
+                    return mSoundTriggerInternal.getModuleProperties();
                 } finally {
                     Binder.restoreCallingIdentity(caller);
                 }
@@ -771,9 +847,9 @@
                         || soundModel.uuid == null
                         || soundModel.keyphrases == null) {
                     Slog.w(TAG, "No matching sound model found in startRecognition");
-                    return SoundTriggerHelper.STATUS_ERROR;
+                    return SoundTriggerInternal.STATUS_ERROR;
                 } else {
-                    return mSoundTriggerHelper.startRecognition(
+                    return mSoundTriggerInternal.startRecognition(
                             keyphraseId, soundModel, callback, recognitionConfig);
                 }
             } finally {
@@ -795,7 +871,7 @@
 
             final long caller = Binder.clearCallingIdentity();
             try {
-                return mSoundTriggerHelper.stopRecognition(keyphraseId, callback);
+                return mSoundTriggerInternal.stopRecognition(keyphraseId, callback);
             } finally {
                 Binder.restoreCallingIdentity(caller);
             }
@@ -937,7 +1013,7 @@
                 }
                 mImpl.dumpLocked(fd, pw, args);
             }
-            mSoundTriggerHelper.dump(fd, pw, args);
+            mSoundTriggerInternal.dump(fd, pw, args);
         }
 
         private void enforceCallingPermission(String permission) {
@@ -986,7 +1062,7 @@
                     // The user is force stopping our current interactor/recognizer.
                     // Clear the current settings and restore default state.
                     synchronized (VoiceInteractionManagerService.this) {
-                        mSoundTriggerHelper.stopAllRecognitions();
+                        mSoundTriggerInternal.stopAllRecognitions();
                         if (mImpl != null) {
                             mImpl.shutdownLocked();
                             mImpl = null;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 3efd0fb..1544723 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -215,12 +215,12 @@
         }
     }
 
-    public void finishLocked(IBinder token) {
-        if (mActiveSession == null || token != mActiveSession.mToken) {
+    public void finishLocked(IBinder token, boolean finishTask) {
+        if (mActiveSession == null || (!finishTask && token != mActiveSession.mToken)) {
             Slog.w(TAG, "finish does not match active session");
             return;
         }
-        mActiveSession.cancelLocked();
+        mActiveSession.cancelLocked(finishTask);
         mActiveSession = null;
     }
 
@@ -251,6 +251,10 @@
         return mActiveSession != null ? mActiveSession.getUserDisabledShowContextLocked() : 0;
     }
 
+    public boolean supportsLocalVoiceInteraction() {
+        return mInfo.getSupportsLocalInteraction();
+    }
+
     public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!mValid) {
             pw.print("  NOT VALID: ");
@@ -308,7 +312,7 @@
         // If there is an active session, cancel it to allow it to clean up its window and other
         // state.
         if (mActiveSession != null) {
-            mActiveSession.cancelLocked();
+            mActiveSession.cancelLocked(false);
             mActiveSession = null;
         }
         try {
@@ -343,7 +347,7 @@
     @Override
     public void sessionConnectionGone(VoiceInteractionSessionConnection connection) {
         synchronized (mLock) {
-            finishLocked(connection.mToken);
+            finishLocked(connection.mToken, false);
         }
     }
 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 1788e88..e04f312 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -418,7 +418,7 @@
         return false;
     }
 
-    public void cancelLocked() {
+    public void cancelLocked(boolean finishTask) {
         hideLocked();
         mCanceled = true;
         if (mBound) {
@@ -429,7 +429,7 @@
                     Slog.w(TAG, "Voice interation session already dead");
                 }
             }
-            if (mSession != null) {
+            if (finishTask && mSession != null) {
                 try {
                     mAm.finishVoiceTask(mSession);
                 } catch (RemoteException e) {
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index aa95e1d..3859294 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -24,7 +24,6 @@
 import java.lang.String;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -210,7 +209,22 @@
          * Call sends responses through connection.
          * @hide
          */
-        public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 0x00400000;
+        public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 0x00200000;
+
+        /**
+         * When set, prevents a video {@code Call} from being downgraded to an audio-only call.
+         * <p>
+         * Should be set when the VideoState has the {@link VideoProfile#STATE_TX_ENABLED} or
+         * {@link VideoProfile#STATE_RX_ENABLED} bits set to indicate that the connection cannot be
+         * downgraded from a video call back to a VideoState of
+         * {@link VideoProfile#STATE_AUDIO_ONLY}.
+         * <p>
+         * Intuitively, a call which can be downgraded to audio should also have local and remote
+         * video
+         * capabilities (see {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and
+         * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL}).
+         */
+        public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 0x00400000;
 
         //******************************************************************************************
         // Next CAPABILITY value: 0x00800000
@@ -332,6 +346,9 @@
             if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_TX)) {
                 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_TX");
             }
+            if (can(capabilities, CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO)) {
+                builder.append(" CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO");
+            }
             if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
                 builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL");
             }
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index deb98f4..fa7a59d 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -255,8 +255,23 @@
      */
     public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 0x00400000;
 
+    /**
+     * When set, prevents a video call from being downgraded to an audio-only call.
+     * <p>
+     * Should be set when the VideoState has the {@link VideoProfile#STATE_TX_ENABLED} or
+     * {@link VideoProfile#STATE_RX_ENABLED} bits set to indicate that the connection cannot be
+     * downgraded from a video call back to a VideoState of
+     * {@link VideoProfile#STATE_AUDIO_ONLY}.
+     * <p>
+     * Intuitively, a call which can be downgraded to audio should also have local and remote
+     * video
+     * capabilities (see {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and
+     * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL}).
+     */
+    public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 0x00800000;
+
     //**********************************************************************************************
-    // Next CAPABILITY value: 0x00800000
+    // Next CAPABILITY value: 0x01000000
     //**********************************************************************************************
 
     /**
@@ -371,6 +386,9 @@
         if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL)) {
             builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL");
         }
+        if (can(capabilities, CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO)) {
+            builder.append(" CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO");
+        }
         if (can(capabilities, CAPABILITY_HIGH_DEF_AUDIO)) {
             builder.append(" CAPABILITY_HIGH_DEF_AUDIO");
         }
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 3e30188..497864e 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -397,27 +397,23 @@
 
     /**
      * Broadcast intent action for letting custom component know to show the missed call
-     * notification.
-     * @hide
+     * notification. If no custom component exists then this is sent to the default dialer which
+     * should post a missed-call notification.
      */
-    @SystemApi
     public static final String ACTION_SHOW_MISSED_CALLS_NOTIFICATION =
             "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
 
     /**
-     * The number of calls associated with the notification.
-     * @hide
+     * The number of calls associated with the notification. If the number is zero then the missed
+     * call notification should be dismissed.
      */
-    @SystemApi
     public static final String EXTRA_NOTIFICATION_COUNT =
             "android.telecom.extra.NOTIFICATION_COUNT";
 
     /**
      * The number associated with the missed calls. This number is only relevant
      * when EXTRA_NOTIFICATION_COUNT is 1.
-     * @hide
      */
-    @SystemApi
     public static final String EXTRA_NOTIFICATION_PHONE_NUMBER =
             "android.telecom.extra.NOTIFICATION_PHONE_NUMBER";
 
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 56e081c..4368b81 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -752,7 +752,7 @@
      */
     @Nullable
     public PersistableBundle getConfig() {
-        return getConfigForSubId(SubscriptionManager.getDefaultSubId());
+        return getConfigForSubId(SubscriptionManager.getDefaultSubscriptionId());
     }
 
     /**
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 90d2aa0..74f1171 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -38,6 +38,10 @@
     private final int mLac;
     // 16-bit GSM Cell Identity described in TS 27.007, 0..65535
     private final int mCid;
+    // 16-bit GSM Absolute RF Channel Number
+    private final int mArfcn;
+    // 6-bit Base Station Identity Code
+    private final int mBsic;
 
     /**
      * @hide
@@ -47,6 +51,8 @@
         mMnc = Integer.MAX_VALUE;
         mLac = Integer.MAX_VALUE;
         mCid = Integer.MAX_VALUE;
+        mArfcn = Integer.MAX_VALUE;
+        mBsic = Integer.MAX_VALUE;
     }
     /**
      * public constructor
@@ -58,10 +64,27 @@
      * @hide
      */
     public CellIdentityGsm (int mcc, int mnc, int lac, int cid) {
+        this(mcc, mnc, lac, cid, Integer.MAX_VALUE, Integer.MAX_VALUE);
+    }
+
+    /**
+     * public constructor
+     * @param mcc 3-digit Mobile Country Code, 0..999
+     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
+     * @param lac 16-bit Location Area Code, 0..65535
+     * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity
+     * @param arfcn 16-bit GSM Absolute RF Channel Number
+     * @param bsic 6-bit Base Station Identity Code
+     *
+     * @hide
+     */
+    public CellIdentityGsm (int mcc, int mnc, int lac, int cid, int arfcn, int bsic) {
         mMcc = mcc;
         mMnc = mnc;
         mLac = lac;
         mCid = cid;
+        mArfcn = arfcn;
+        mBsic = bsic;
     }
 
     private CellIdentityGsm(CellIdentityGsm cid) {
@@ -69,6 +92,8 @@
         mMnc = cid.mMnc;
         mLac = cid.mLac;
         mCid = cid.mCid;
+        mArfcn = cid.mArfcn;
+        mBsic = cid.mBsic;
     }
 
     CellIdentityGsm copy() {
@@ -106,6 +131,21 @@
     }
 
     /**
+     * @return 16-bit GSM Absolute RF Channel Number, Integer.MAX_VALUE if unknown
+     */
+    public int getArfcn() {
+        return mArfcn;
+    }
+
+    /**
+     * @return 6-bit Base Station Identity Code, Integer.MAX_VALUE if unknown
+     */
+    public int getBsic() {
+        return mBsic;
+    }
+
+
+    /**
      * @return Integer.MAX_VALUE, undefined for GSM
      */
     @Deprecated
@@ -132,7 +172,9 @@
         return mMcc == o.mMcc &&
                 mMnc == o.mMnc &&
                 mLac == o.mLac &&
-                mCid == o.mCid;
+                mCid == o.mCid &&
+                mArfcn == o.mArfcn &&
+                mBsic == o.mBsic;
     }
 
     @Override
@@ -142,6 +184,8 @@
         sb.append(" mMnc=").append(mMnc);
         sb.append(" mLac=").append(mLac);
         sb.append(" mCid=").append(mCid);
+        sb.append(" mArfcn=").append(mArfcn);
+        sb.append(" mBsic=").append("0x").append(Integer.toHexString(mBsic));
         sb.append("}");
 
         return sb.toString();
@@ -161,6 +205,8 @@
         dest.writeInt(mMnc);
         dest.writeInt(mLac);
         dest.writeInt(mCid);
+        dest.writeInt(mArfcn);
+        dest.writeInt(mBsic);
     }
 
     /** Construct from Parcel, type has already been processed */
@@ -169,6 +215,8 @@
         mMnc = in.readInt();
         mLac = in.readInt();
         mCid = in.readInt();
+        mArfcn = in.readInt();
+        mBsic = in.readInt();
         if (DBG) log("CellIdentityGsm(Parcel): " + toString());
     }
 
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 1e7ac08..ce74383 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -40,6 +40,8 @@
     private final int mPci;
     // 16-bit tracking area code
     private final int mTac;
+    // 18-bit Absolute RF Channel Number
+    private final int mEarfcn;
 
     /**
      * @hide
@@ -50,6 +52,7 @@
         mCi = Integer.MAX_VALUE;
         mPci = Integer.MAX_VALUE;
         mTac = Integer.MAX_VALUE;
+        mEarfcn = Integer.MAX_VALUE;
     }
 
     /**
@@ -63,11 +66,27 @@
      * @hide
      */
     public CellIdentityLte (int mcc, int mnc, int ci, int pci, int tac) {
+        this(mcc, mnc, ci, pci, tac, Integer.MAX_VALUE);
+    }
+
+    /**
+     *
+     * @param mcc 3-digit Mobile Country Code, 0..999
+     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
+     * @param ci 28-bit Cell Identity
+     * @param pci Physical Cell Id 0..503
+     * @param tac 16-bit Tracking Area Code
+     * @param earfcn 18-bit LTE Absolute RF Channel Number
+     *
+     * @hide
+     */
+    public CellIdentityLte (int mcc, int mnc, int ci, int pci, int tac, int earfcn) {
         mMcc = mcc;
         mMnc = mnc;
         mCi = ci;
         mPci = pci;
         mTac = tac;
+        mEarfcn = earfcn;
     }
 
     private CellIdentityLte(CellIdentityLte cid) {
@@ -76,6 +95,7 @@
         mCi = cid.mCi;
         mPci = cid.mPci;
         mTac = cid.mTac;
+        mEarfcn = cid.mEarfcn;
     }
 
     CellIdentityLte copy() {
@@ -117,6 +137,13 @@
         return mTac;
     }
 
+    /**
+     * @return 18-bit Absolute RF Channel Number, Integer.MAX_VALUE if unknown
+     */
+    public int getEarfcn() {
+        return mEarfcn;
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(mMcc, mMnc, mCi, mPci, mTac);
@@ -137,7 +164,8 @@
                 mMnc == o.mMnc &&
                 mCi == o.mCi &&
                 mPci == o.mPci &&
-                mTac == o.mTac;
+                mTac == o.mTac &&
+                mEarfcn == o.mEarfcn;
     }
 
     @Override
@@ -148,6 +176,7 @@
         sb.append(" mCi="); sb.append(mCi);
         sb.append(" mPci="); sb.append(mPci);
         sb.append(" mTac="); sb.append(mTac);
+        sb.append(" mEarfcn="); sb.append(mEarfcn);
         sb.append("}");
 
         return sb.toString();
@@ -168,6 +197,7 @@
         dest.writeInt(mCi);
         dest.writeInt(mPci);
         dest.writeInt(mTac);
+        dest.writeInt(mEarfcn);
     }
 
     /** Construct from Parcel, type has already been processed */
@@ -177,6 +207,7 @@
         mCi = in.readInt();
         mPci = in.readInt();
         mTac = in.readInt();
+        mEarfcn = in.readInt();
         if (DBG) log("CellIdentityLte(Parcel): " + toString());
     }
 
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 56ee8c9..0d13efd 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -40,6 +40,8 @@
     private final int mCid;
     // 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511
     private final int mPsc;
+    // 16-bit UMTS Absolute RF Channel Number
+    private final int mUarfcn;
 
     /**
      * @hide
@@ -50,6 +52,7 @@
         mLac = Integer.MAX_VALUE;
         mCid = Integer.MAX_VALUE;
         mPsc = Integer.MAX_VALUE;
+        mUarfcn = Integer.MAX_VALUE;
     }
     /**
      * public constructor
@@ -62,11 +65,27 @@
      * @hide
      */
     public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc) {
+        this(mcc, mnc, lac, cid, psc, Integer.MAX_VALUE);
+    }
+
+    /**
+     * public constructor
+     * @param mcc 3-digit Mobile Country Code, 0..999
+     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
+     * @param lac 16-bit Location Area Code, 0..65535
+     * @param cid 28-bit UMTS Cell Identity
+     * @param psc 9-bit UMTS Primary Scrambling Code
+     * @param uarfcn 16-bit UMTS Absolute RF Channel Number
+     *
+     * @hide
+     */
+    public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc, int uarfcn) {
         mMcc = mcc;
         mMnc = mnc;
         mLac = lac;
         mCid = cid;
         mPsc = psc;
+        mUarfcn = uarfcn;
     }
 
     private CellIdentityWcdma(CellIdentityWcdma cid) {
@@ -75,6 +94,7 @@
         mLac = cid.mLac;
         mCid = cid.mCid;
         mPsc = cid.mPsc;
+        mUarfcn = cid.mUarfcn;
     }
 
     CellIdentityWcdma copy() {
@@ -123,6 +143,13 @@
         return Objects.hash(mMcc, mMnc, mLac, mCid, mPsc);
     }
 
+    /**
+     * @return 16-bit UMTS Absolute RF Channel Number, Integer.MAX_VALUE if unknown
+     */
+    public int getUarfcn() {
+        return mUarfcn;
+    }
+
     @Override
     public boolean equals(Object other) {
         if (this == other) {
@@ -138,7 +165,8 @@
                 mMnc == o.mMnc &&
                 mLac == o.mLac &&
                 mCid == o.mCid &&
-                mPsc == o.mPsc;
+                mPsc == o.mPsc &&
+                mUarfcn == o.mUarfcn;
     }
 
     @Override
@@ -149,6 +177,7 @@
         sb.append(" mLac=").append(mLac);
         sb.append(" mCid=").append(mCid);
         sb.append(" mPsc=").append(mPsc);
+        sb.append(" mUarfcn=").append(mUarfcn);
         sb.append("}");
 
         return sb.toString();
@@ -169,6 +198,7 @@
         dest.writeInt(mLac);
         dest.writeInt(mCid);
         dest.writeInt(mPsc);
+        dest.writeInt(mUarfcn);
     }
 
     /** Construct from Parcel, type has already been processed */
@@ -178,6 +208,7 @@
         mLac = in.readInt();
         mCid = in.readInt();
         mPsc = in.readInt();
+        mUarfcn = in.readInt();
         if (DBG) log("CellIdentityWcdma(Parcel): " + toString());
     }
 
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index d27fcec..addf7ef 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -34,6 +34,7 @@
 
     private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
     private int mBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
+    private int mTimingAdvance;
 
     /**
      * Empty constructor
@@ -75,6 +76,22 @@
     public void initialize(int ss, int ber) {
         mSignalStrength = ss;
         mBitErrorRate = ber;
+        mTimingAdvance = Integer.MAX_VALUE;
+    }
+
+    /**
+     * Initialize all the values
+     *
+     * @param ss SignalStrength as ASU value
+     * @param ber is Bit Error Rate
+     * @param ta timing advance
+     *
+     * @hide
+     */
+    public void initialize(int ss, int ber, int ta) {
+        mSignalStrength = ss;
+        mBitErrorRate = ber;
+        mTimingAdvance = ta;
     }
 
     /**
@@ -83,6 +100,7 @@
     protected void copyFrom(CellSignalStrengthGsm s) {
         mSignalStrength = s.mSignalStrength;
         mBitErrorRate = s.mBitErrorRate;
+        mTimingAdvance = s.mTimingAdvance;
     }
 
     /**
@@ -98,6 +116,7 @@
     public void setDefaultValues() {
         mSignalStrength = Integer.MAX_VALUE;
         mBitErrorRate = Integer.MAX_VALUE;
+        mTimingAdvance = Integer.MAX_VALUE;
     }
 
     /**
@@ -174,7 +193,8 @@
             return false;
         }
 
-        return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate;
+        return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate &&
+                        s.mTimingAdvance == mTimingAdvance;
     }
 
     /**
@@ -184,7 +204,8 @@
     public String toString() {
         return "CellSignalStrengthGsm:"
                 + " ss=" + mSignalStrength
-                + " ber=" + mBitErrorRate;
+                + " ber=" + mBitErrorRate
+                + " mTa=" + mTimingAdvance;
     }
 
     /** Implement the Parcelable interface */
@@ -193,6 +214,7 @@
         if (DBG) log("writeToParcel(Parcel, int): " + toString());
         dest.writeInt(mSignalStrength);
         dest.writeInt(mBitErrorRate);
+        dest.writeInt(mTimingAdvance);
     }
 
     /**
@@ -202,6 +224,7 @@
     private CellSignalStrengthGsm(Parcel in) {
         mSignalStrength = in.readInt();
         mBitErrorRate = in.readInt();
+        mTimingAdvance = in.readInt();
         if (DBG) log("CellSignalStrengthGsm(Parcel): " + toString());
     }
 
diff --git a/telephony/java/android/telephony/DataConnectionRealTimeInfo.java b/telephony/java/android/telephony/DataConnectionRealTimeInfo.java
index 96069213..f71f58d 100644
--- a/telephony/java/android/telephony/DataConnectionRealTimeInfo.java
+++ b/telephony/java/android/telephony/DataConnectionRealTimeInfo.java
@@ -28,10 +28,10 @@
 public class DataConnectionRealTimeInfo implements Parcelable {
     private long mTime;             // Time the info was collected since boot in nanos;
 
-    public static int DC_POWER_STATE_LOW       = 1;
-    public static int DC_POWER_STATE_MEDIUM    = 2;
-    public static int DC_POWER_STATE_HIGH      = 3;
-    public static int DC_POWER_STATE_UNKNOWN   = Integer.MAX_VALUE;
+    public static final int DC_POWER_STATE_LOW       = 1;
+    public static final int DC_POWER_STATE_MEDIUM    = 2;
+    public static final int DC_POWER_STATE_HIGH      = 3;
+    public static final int DC_POWER_STATE_UNKNOWN   = Integer.MAX_VALUE;
 
     private int mDcPowerState;      // DC_POWER_STATE_[LOW | MEDIUM | HIGH | UNKNOWN]
 
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 553221d..b089387 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -2082,7 +2082,7 @@
      * to read the VM number.
      */
     public static boolean isVoiceMailNumber(String number) {
-        return isVoiceMailNumber(SubscriptionManager.getDefaultSubId(), number);
+        return isVoiceMailNumber(SubscriptionManager.getDefaultSubscriptionId(), number);
     }
 
     /**
@@ -2977,7 +2977,7 @@
      * Returns Default voice subscription Id.
      */
     private static int getDefaultVoiceSubId() {
-        return SubscriptionManager.getDefaultVoiceSubId();
+        return SubscriptionManager.getDefaultVoiceSubscriptionId();
     }
     //==== End of utility methods used only in compareStrictly() =====
 }
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 16472c8..ae130d4 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -194,10 +194,12 @@
      * {@more}
      * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
      * READ_PRECISE_PHONE_STATE}
-     *
      * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
+     *
+     * @deprecated Use {@link TelephonyManager#getModemActivityInfo()}
      * @hide
      */
+    @Deprecated
     public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO           = 0x00002000;
 
     /**
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 9998937..ff8c71c 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -53,7 +53,6 @@
     private static final boolean VDBG = false;
 
     /** An invalid subscription identifier */
-    /** @hide */
     public static final int INVALID_SUBSCRIPTION_ID = -1;
 
     /** Base value for Dummy SUBSCRIPTION_ID's. */
@@ -455,8 +454,9 @@
     }
 
     /**
-     * Get the active SubscriptionInfo with the subId key
-     * @param subId The unique SubscriptionInfo key in database
+     * Get the active SubscriptionInfo with the input subId.
+     *
+     * @param subId The unique SubscriptionInfo key in database.
      * @return SubscriptionInfo, maybe null if its not active.
      */
     public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
@@ -898,12 +898,15 @@
     }
 
     /**
-     * @return the "system" defaultSubId on a voice capable device this
-     * will be getDefaultVoiceSubId() and on a data only device it will be
-     * getDefaultDataSubId().
-     * @hide
+     * Returns the system's default subscription id.
+     *
+     * For a voice capable device, it will return getDefaultVoiceSubscriptionId.
+     * For a data only device, it will return the getDefaultDataSubscriptionId.
+     * May return an INVALID_SUBSCRIPTION_ID on error.
+     *
+     * @return the "system" default subscription id.
      */
-    public static int getDefaultSubId() {
+    public static int getDefaultSubscriptionId() {
         int subId = INVALID_SUBSCRIPTION_ID;
 
         try {
@@ -919,8 +922,14 @@
         return subId;
     }
 
-    /** @hide */
-    public static int getDefaultVoiceSubId() {
+    /**
+     * Returns the system's default voice subscription id.
+     *
+     * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
+     *
+     * @return the default voice subscription Id.
+     */
+    public static int getDefaultVoiceSubscriptionId() {
         int subId = INVALID_SUBSCRIPTION_ID;
 
         try {
@@ -932,7 +941,7 @@
             // ignore it
         }
 
-        if (VDBG) logd("getDefaultVoiceSubId, sub id = " + subId);
+        if (VDBG) logd("getDefaultVoiceSubscriptionId, sub id = " + subId);
         return subId;
     }
 
@@ -949,23 +958,31 @@
         }
     }
 
-    /** @hide */
+    /**
+     * Return the SubscriptionInfo for default voice subscription.
+     *
+     * Will return null on data only devices, or on error.
+     *
+     * @return the SubscriptionInfo for the default voice subscription.
+     * @hide
+     */
     public SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
-        return getActiveSubscriptionInfo(getDefaultVoiceSubId());
+        return getActiveSubscriptionInfo(getDefaultVoiceSubscriptionId());
     }
 
     /** @hide */
     public static int getDefaultVoicePhoneId() {
-        return getPhoneId(getDefaultVoiceSubId());
+        return getPhoneId(getDefaultVoiceSubscriptionId());
     }
 
     /**
-     * @return subId of the DefaultSms subscription or
-     * a value < 0 if an error.
+     * Returns the system's default SMS subscription id.
      *
-     * @hide
+     * On a data only device or on error, will return INVALID_SUBSCRIPTION_ID.
+     *
+     * @return the default SMS subscription Id.
      */
-    public static int getDefaultSmsSubId() {
+    public static int getDefaultSmsSubscriptionId() {
         int subId = INVALID_SUBSCRIPTION_ID;
 
         try {
@@ -977,7 +994,7 @@
             // ignore it
         }
 
-        if (VDBG) logd("getDefaultSmsSubId, sub id = " + subId);
+        if (VDBG) logd("getDefaultSmsSubscriptionId, sub id = " + subId);
         return subId;
     }
 
@@ -994,18 +1011,31 @@
         }
     }
 
-    /** @hide */
+    /**
+     * Return the SubscriptionInfo for default voice subscription.
+     *
+     * Will return null on data only devices, or on error.
+     *
+     * @return the SubscriptionInfo for the default SMS subscription.
+     * @hide
+     */
     public SubscriptionInfo getDefaultSmsSubscriptionInfo() {
-        return getActiveSubscriptionInfo(getDefaultSmsSubId());
+        return getActiveSubscriptionInfo(getDefaultSmsSubscriptionId());
     }
 
     /** @hide */
     public int getDefaultSmsPhoneId() {
-        return getPhoneId(getDefaultSmsSubId());
+        return getPhoneId(getDefaultSmsSubscriptionId());
     }
 
-    /** @hide */
-    public static int getDefaultDataSubId() {
+    /**
+     * Returns the system's default data subscription id.
+     *
+     * On a voice only device or on error, will return INVALID_SUBSCRIPTION_ID.
+     *
+     * @return the default data subscription Id.
+     */
+    public static int getDefaultDataSubscriptionId() {
         int subId = INVALID_SUBSCRIPTION_ID;
 
         try {
@@ -1017,7 +1047,7 @@
             // ignore it
         }
 
-        if (VDBG) logd("getDefaultDataSubId, sub id = " + subId);
+        if (VDBG) logd("getDefaultDataSubscriptionId, sub id = " + subId);
         return subId;
     }
 
@@ -1034,14 +1064,21 @@
         }
     }
 
-    /** @hide */
+    /**
+     * Return the SubscriptionInfo for default data subscription.
+     *
+     * Will return null on voice only devices, or on error.
+     *
+     * @return the SubscriptionInfo for the default data subscription.
+     * @hide
+     */
     public SubscriptionInfo getDefaultDataSubscriptionInfo() {
-        return getActiveSubscriptionInfo(getDefaultDataSubId());
+        return getActiveSubscriptionInfo(getDefaultDataSubscriptionId());
     }
 
     /** @hide */
     public int getDefaultDataPhoneId() {
-        return getPhoneId(getDefaultDataSubId());
+        return getPhoneId(getDefaultDataSubscriptionId());
     }
 
     /** @hide */
@@ -1061,13 +1098,13 @@
     //FIXME this is vulnerable to race conditions
     /** @hide */
     public boolean allDefaultsSelected() {
-        if (!isValidSubscriptionId(getDefaultDataSubId())) {
+        if (!isValidSubscriptionId(getDefaultDataSubscriptionId())) {
             return false;
         }
-        if (!isValidSubscriptionId(getDefaultSmsSubId())) {
+        if (!isValidSubscriptionId(getDefaultSmsSubscriptionId())) {
             return false;
         }
-        if (!isValidSubscriptionId(getDefaultVoiceSubId())) {
+        if (!isValidSubscriptionId(getDefaultVoiceSubscriptionId())) {
             return false;
         }
         return true;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 7eaa6a6..fcb42a4 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1232,7 +1232,6 @@
      * on a CDMA network).
      * @param subId
      */
-    /** {@hide} */
     public String getNetworkOperatorName(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ALPHA, "");
@@ -1259,8 +1258,7 @@
      *
      * @param subId
      */
-    /** {@hide} */
-   public String getNetworkOperatorForSubscription(int subId) {
+    public String getNetworkOperator(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getNetworkOperatorForPhone(phoneId);
      }
@@ -1276,7 +1274,7 @@
      * @param phoneId
      * @hide
      **/
-   public String getNetworkOperatorForPhone(int phoneId) {
+    public String getNetworkOperatorForPhone(int phoneId) {
         return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
      }
 
@@ -1298,7 +1296,6 @@
      *
      * @param subId
      */
-    /** {@hide} */
     public boolean isNetworkRoaming(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return Boolean.parseBoolean(getTelephonyProperty(phoneId,
@@ -1327,8 +1324,7 @@
      *
      * @param subId for which Network CountryIso is returned
      */
-    /** {@hide} */
-    public String getNetworkCountryIsoForSubscription(int subId) {
+    public String getNetworkCountryIso(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getNetworkCountryIsoForPhone(phoneId);
     }
@@ -1436,7 +1432,6 @@
      * Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
-    /** {@hide} */
    public int getNetworkType(int subId) {
        try {
            ITelephony telephony = getITelephony();
@@ -1497,7 +1492,6 @@
      * Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
-    /** {@hide} */
     public int getDataNetworkType(int subId) {
         try{
             ITelephony telephony = getITelephony();
@@ -1535,7 +1529,6 @@
      * Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
-    /** {@hide} */
     public int getVoiceNetworkType(int subId) {
         try{
             ITelephony telephony = getITelephony();
@@ -1804,10 +1797,9 @@
      * @see #getSimState
      *
      * @param subId for which SimOperator is returned
-     * @hide
      */
     public String getSimOperator(int subId) {
-        return getSimOperatorNumericForSubscription(subId);
+        return getSimOperatorNumeric(subId);
     }
 
     /**
@@ -1820,17 +1812,17 @@
      * @hide
      */
     public String getSimOperatorNumeric() {
-        int subId = SubscriptionManager.getDefaultDataSubId();
+        int subId = SubscriptionManager.getDefaultDataSubscriptionId();
         if (!SubscriptionManager.isUsableSubIdValue(subId)) {
-            subId = SubscriptionManager.getDefaultSmsSubId();
+            subId = SubscriptionManager.getDefaultSmsSubscriptionId();
             if (!SubscriptionManager.isUsableSubIdValue(subId)) {
-                subId = SubscriptionManager.getDefaultVoiceSubId();
+                subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
                 if (!SubscriptionManager.isUsableSubIdValue(subId)) {
-                    subId = SubscriptionManager.getDefaultSubId();
+                    subId = SubscriptionManager.getDefaultSubscriptionId();
                 }
             }
         }
-        return getSimOperatorNumericForSubscription(subId);
+        return getSimOperatorNumeric(subId);
     }
 
     /**
@@ -1844,7 +1836,7 @@
      * @param subId for which SimOperator is returned
      * @hide
      */
-    public String getSimOperatorNumericForSubscription(int subId) {
+    public String getSimOperatorNumeric(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getSimOperatorNumericForPhone(phoneId);
     }
@@ -1881,9 +1873,8 @@
      * @see #getSimState
      *
      * @param subId for which SimOperatorName is returned
-     * @hide
      */
-    public String getSimOperatorNameForSubscription(int subId) {
+    public String getSimOperatorName(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getSimOperatorNameForPhone(phoneId);
     }
@@ -1909,21 +1900,8 @@
      * Returns the ISO country code equivalent for the SIM provider's country code.
      *
      * @param subId for which SimCountryIso is returned
-     *
-     * @hide
      */
     public String getSimCountryIso(int subId) {
-        return getSimCountryIsoForSubscription(subId);
-    }
-
-    /**
-     * Returns the ISO country code equivalent for the SIM provider's country code.
-     *
-     * @param subId for which SimCountryIso is returned
-     *
-     * @hide
-     */
-    public String getSimCountryIsoForSubscription(int subId) {
         int phoneId = SubscriptionManager.getPhoneId(subId);
         return getSimCountryIsoForPhone(phoneId);
     }
@@ -1957,7 +1935,6 @@
      * Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
-    /** {@hide} */
     public String getSimSerialNumber(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2046,7 +2023,6 @@
      *
      * @param subId whose subscriber id is returned
      */
-    /** {@hide} */
     public String getSubscriberId(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2089,9 +2065,8 @@
      * Requires Permission:
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      *
-     * @param subscription whose subscriber id is returned
+     * @param subId whose subscriber id is returned
      */
-    /** {@hide} */
     public String getGroupIdLevel1(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2118,7 +2093,7 @@
      * The default SMS app can also use this.
      */
     public String getLine1Number() {
-        return getLine1NumberForSubscriber(getDefaultSubscription());
+        return getLine1Number(getDefaultSubscription());
     }
 
     /**
@@ -2134,8 +2109,7 @@
      *
      * @param subId whose phone number for line 1 is returned
      */
-    /** {@hide} */
-    public String getLine1NumberForSubscriber(int subId) {
+    public String getLine1Number(int subId) {
         String number = null;
         try {
             ITelephony telephony = getITelephony();
@@ -2174,7 +2148,7 @@
      * @return true if the operation was executed correctly.
      */
     public boolean setLine1NumberForDisplay(String alphaTag, String number) {
-        return setLine1NumberForDisplayForSubscriber(getDefaultSubscription(), alphaTag, number);
+        return setLine1NumberForDisplay(getDefaultSubscription(), alphaTag, number);
     }
 
     /**
@@ -2190,9 +2164,8 @@
      * @param alphaTag alpha-tagging of the dailing nubmer
      * @param number The dialing number
      * @return true if the operation was executed correctly.
-     * @hide
      */
-    public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number) {
+    public boolean setLine1NumberForDisplay(int subId, String alphaTag, String number) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
@@ -2213,7 +2186,7 @@
      * nobody seems to call this.
      */
     public String getLine1AlphaTag() {
-        return getLine1AlphaTagForSubscriber(getDefaultSubscription());
+        return getLine1AlphaTag(getDefaultSubscription());
     }
 
     /**
@@ -2226,8 +2199,7 @@
      * @param subId whose alphabetic identifier associated with line 1 is returned
      * nobody seems to call this.
      */
-    /** {@hide} */
-    public String getLine1AlphaTagForSubscriber(int subId) {
+    public String getLine1AlphaTag(int subId) {
         String alphaTag = null;
         try {
             ITelephony telephony = getITelephony();
@@ -2327,7 +2299,6 @@
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @param subId whose voice mail number is returned
      */
-    /** {@hide} */
     public String getVoiceMailNumber(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2400,7 +2371,6 @@
      * @param alphaTag The alpha tag to display.
      * @param number The voicemail number.
      */
-    /** {@hide} */
     public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
         try {
             ITelephony telephony = getITelephony();
@@ -2466,7 +2436,6 @@
      * @param subId whose alphabetic identifier associated with the
      * voice mail number is returned
      */
-    /** {@hide} */
     public String getVoiceMailAlphaTag(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2584,7 +2553,6 @@
      *
      * @param subId whose call state is returned
      */
-    /** {@hide} */
     public int getCallState(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -3225,19 +3193,19 @@
      * Returns Default subscription.
      */
     private static int getDefaultSubscription() {
-        return SubscriptionManager.getDefaultSubId();
+        return SubscriptionManager.getDefaultSubscriptionId();
     }
 
     /**
      * Returns Default phone.
      */
     private static int getDefaultPhone() {
-        return SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubId());
+        return SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId());
     }
 
     /** {@hide} */
     public int getDefaultSim() {
-        return SubscriptionManager.getSlotId(SubscriptionManager.getDefaultSubId());
+        return SubscriptionManager.getSlotId(SubscriptionManager.getDefaultSubscriptionId());
     }
 
     /**
@@ -4182,7 +4150,7 @@
     /** @hide */
     @SystemApi
     public void setDataEnabled(boolean enable) {
-        setDataEnabled(SubscriptionManager.getDefaultDataSubId(), enable);
+        setDataEnabled(SubscriptionManager.getDefaultDataSubscriptionId(), enable);
     }
 
     /** @hide */
@@ -4201,7 +4169,7 @@
     /** @hide */
     @SystemApi
     public boolean getDataEnabled() {
-        return getDataEnabled(SubscriptionManager.getDefaultDataSubId());
+        return getDataEnabled(SubscriptionManager.getDefaultDataSubscriptionId());
     }
 
     /** @hide */
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index b9d7297..5f3f773 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -327,7 +327,7 @@
     public static CallerInfo getCallerInfo(Context context, String number) {
         if (VDBG) Rlog.v(TAG, "getCallerInfo() based on number...");
 
-        int subId = SubscriptionManager.getDefaultSubId();
+        int subId = SubscriptionManager.getDefaultSubscriptionId();
         return getCallerInfo(context, number, subId);
     }
 
@@ -444,7 +444,7 @@
     // string in the phone number field.
     /* package */ CallerInfo markAsVoiceMail() {
 
-        int subId = SubscriptionManager.getDefaultSubId();
+        int subId = SubscriptionManager.getDefaultSubscriptionId();
         return markAsVoiceMail(subId);
 
     }
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index c754068..05cb31e 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -387,7 +387,7 @@
     public static CallerInfoAsyncQuery startQuery(int token, Context context, String number,
             OnQueryCompleteListener listener, Object cookie) {
 
-        int subId = SubscriptionManager.getDefaultSubId();
+        int subId = SubscriptionManager.getDefaultSubscriptionId();
         return startQuery(token, context, number, listener, cookie, subId);
     }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 76b69ce..907d76e 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -21,7 +21,6 @@
 import android.net.NetworkCapabilities;
 import android.os.Bundle;
 import android.telephony.CellInfo;
-import android.telephony.DataConnectionRealTimeInfo;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.CellInfo;
@@ -65,7 +64,6 @@
     void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
             String failCause);
     void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo);
-    void notifyDataConnectionRealTimeInfo(in DataConnectionRealTimeInfo dcRtInfo);
     void notifyVoLteServiceStateChanged(in VoLteServiceState lteState);
     void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData);
     void notifySubscriptionInfoChanged();
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
index 0c36063..4c12c2d 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
@@ -16,8 +16,9 @@
 
 package android.security.net.config;
 
-import java.util.Set;
+import android.util.ArraySet;
 import java.security.cert.X509Certificate;
+import java.util.Set;
 
 import com.android.org.conscrypt.TrustedCertificateIndex;
 
@@ -33,10 +34,12 @@
         }
     }
 
+    @Override
     public Set<X509Certificate> getCertificates() {
             return mCertificates;
     }
 
+    @Override
     public X509Certificate findBySubjectAndPublicKey(X509Certificate cert) {
         java.security.cert.TrustAnchor anchor = mIndex.findBySubjectAndPublicKey(cert);
         if (anchor == null) {
@@ -45,6 +48,7 @@
         return anchor.getTrustedCert();
     }
 
+    @Override
     public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
         java.security.cert.TrustAnchor anchor = mIndex.findByIssuerAndSignature(cert);
         if (anchor == null) {
@@ -52,4 +56,13 @@
         }
         return anchor.getTrustedCert();
     }
+
+    @Override
+    public Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert) {
+        Set<X509Certificate> certs = new ArraySet<X509Certificate>();
+        for (java.security.cert.TrustAnchor anchor : mIndex.findAllByIssuerAndSignature(cert)) {
+            certs.add(anchor.getTrustedCert());
+        }
+        return certs;
+    }
 }
diff --git a/tests/SoundTriggerTestApp/Android.mk b/tests/SoundTriggerTestApp/Android.mk
new file mode 100644
index 0000000..7bcab5e
--- /dev/null
+++ b/tests/SoundTriggerTestApp/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := SoundTriggerTestApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRIVILEGED_MODULE := true
+
+include $(BUILD_PACKAGE)
diff --git a/tests/SoundTriggerTestApp/AndroidManifest.xml b/tests/SoundTriggerTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..40619da
--- /dev/null
+++ b/tests/SoundTriggerTestApp/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.test.soundtrigger">
+
+    <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" />
+    <application
+         android:permission="android.permission.MANAGE_SOUND_TRIGGER">
+        <activity
+            android:name="TestSoundTriggerActivity"
+            android:label="SoundTrigger Test Application"
+            android:theme="@android:style/Theme.Material.Light.Voice">
+            <intent-filter>
+                <action android:name="com.android.intent.action.MANAGE_SOUND_TRIGGER" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/SoundTriggerTestApp/res/layout/main.xml b/tests/SoundTriggerTestApp/res/layout/main.xml
new file mode 100644
index 0000000..9d2b9d9
--- /dev/null
+++ b/tests/SoundTriggerTestApp/res/layout/main.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="match_parent"
+    >
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/enroll"
+        android:onClick="onEnrollButtonClicked"
+        android:padding="20dp" />
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/reenroll"
+        android:onClick="onReEnrollButtonClicked"
+        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
diff --git a/tests/SoundTriggerTestApp/res/values/strings.xml b/tests/SoundTriggerTestApp/res/values/strings.xml
new file mode 100644
index 0000000..07bac2a
--- /dev/null
+++ b/tests/SoundTriggerTestApp/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 Google Inc.
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <string name="enroll">Enroll</string>
+    <string name="reenroll">Re-enroll</string>
+    <string name="unenroll">Un-enroll</string>
+</resources>
\ No newline at end of file
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java
new file mode 100644
index 0000000..4702835
--- /dev/null
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.soundtrigger;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.media.soundtrigger.SoundTriggerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import com.android.internal.app.ISoundTriggerService;
+
+import java.util.UUID;
+
+/**
+ * Utility class for the managing sound trigger sound models.
+ */
+public class SoundTriggerUtil {
+    private static final String TAG = "TestSoundTriggerUtil:Hotsound";
+
+    private final ISoundTriggerService mSoundTriggerService;
+    private final SoundTriggerManager mSoundTriggerManager;
+    private final Context mContext;
+
+    public SoundTriggerUtil(Context context) {
+        mSoundTriggerService = ISoundTriggerService.Stub.asInterface(
+                ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE));
+        mSoundTriggerManager = (SoundTriggerManager) context.getSystemService(
+                Context.SOUND_TRIGGER_SERVICE);
+        mContext = context;
+    }
+
+    /**
+     * Adds/Updates a sound model.
+     * The sound model must contain a valid UUID.
+     *
+     * @param soundModel The sound model to add/update.
+     */
+    public boolean addOrUpdateSoundModel(GenericSoundModel soundModel) {
+        try {
+            mSoundTriggerService.updateSoundModel(soundModel);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in updateSoundModel", e);
+        }
+        return true;
+    }
+
+    public void addOrUpdateSoundModel(SoundTriggerManager.Model soundModel) {
+        mSoundTriggerManager.updateModel(soundModel);
+    }
+
+    /**
+     * Gets the sound model for the given keyphrase, null if none exists.
+     * If a sound model for a given keyphrase exists, and it needs to be updated,
+     * it should be obtained using this method, updated and then passed in to
+     * {@link #addOrUpdateSoundModel(GenericSoundModel)} without changing the IDs.
+     *
+     * @param modelId The model ID to look-up the sound model for.
+     * @return The sound model if one was found, null otherwise.
+     */
+    @Nullable
+    public GenericSoundModel getSoundModel(UUID modelId) {
+        GenericSoundModel model = null;
+        try {
+            model = mSoundTriggerService.getSoundModel(new ParcelUuid(modelId));
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in updateKeyphraseSoundModel");
+        }
+
+        if (model == null) {
+            Log.w(TAG, "No models present for the gien keyphrase ID");
+            return null;
+        } else {
+            return model;
+        }
+    }
+
+    /**
+     * Deletes the sound model for the given keyphrase id.
+     *
+     * @param modelId The model ID to look-up the sound model for.
+     * @return {@code true} if the call succeeds, {@code false} otherwise.
+     */
+    @Nullable
+    public boolean deleteSoundModel(UUID modelId) {
+        try {
+            mSoundTriggerService.deleteSoundModel(new ParcelUuid(modelId));
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in updateSoundModel");
+        }
+        return true;
+    }
+
+    public void deleteSoundModelUsingManager(UUID modelId) {
+            mSoundTriggerManager.deleteModel(modelId);
+    }
+}
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
new file mode 100644
index 0000000..966179b
--- /dev/null
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.soundtrigger;
+
+import java.util.Random;
+import java.util.UUID;
+
+import android.app.Activity;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.media.soundtrigger.SoundTriggerManager;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+public class TestSoundTriggerActivity extends Activity {
+    private static final String TAG = "TestSoundTriggerActivity";
+    private static final boolean DBG = true;
+
+    private SoundTriggerUtil mSoundTriggerUtil;
+    private Random mRandom;
+    private UUID mModelUuid = UUID.randomUUID();
+    private UUID mModelUuid2 = UUID.randomUUID();
+    private UUID mVendorUuid = UUID.randomUUID();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        if (DBG) Log.d(TAG, "onCreate");
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+        mSoundTriggerUtil = new SoundTriggerUtil(this);
+        mRandom = new Random();
+    }
+
+    /**
+     * Called when the user clicks the enroll button.
+     * Performs a fresh enrollment.
+     */
+    public void onEnrollButtonClicked(View v) {
+        // Generate a fake model to push.
+        byte[] data = new byte[1024];
+        mRandom.nextBytes(data);
+        GenericSoundModel model = new GenericSoundModel(mModelUuid, mVendorUuid, data);
+
+        boolean status = mSoundTriggerUtil.addOrUpdateSoundModel(model);
+        if (status) {
+            Toast.makeText(
+                    this, "Successfully created sound trigger model UUID=" + mModelUuid, Toast.LENGTH_SHORT)
+                    .show();
+        } else {
+            Toast.makeText(this, "Failed to enroll!!!" + mModelUuid, Toast.LENGTH_SHORT).show();
+        }
+
+        // Test the SoundManager API.
+        SoundTriggerManager.Model tmpModel = SoundTriggerManager.Model.create(mModelUuid2,
+                mVendorUuid, data);
+        mSoundTriggerUtil.addOrUpdateSoundModel(tmpModel);
+    }
+
+    /**
+     * Called when the user clicks the un-enroll button.
+     * Clears the enrollment information for the user.
+     */
+    public void onUnEnrollButtonClicked(View v) {
+        GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(mModelUuid);
+        if (soundModel == null) {
+            Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show();
+            return;
+        }
+        boolean status = mSoundTriggerUtil.deleteSoundModel(mModelUuid);
+        if (status) {
+            Toast.makeText(this, "Successfully deleted model UUID=" + soundModel.uuid,
+                    Toast.LENGTH_SHORT)
+                    .show();
+        } else {
+            Toast.makeText(this, "Failed to delete sound model!!!", Toast.LENGTH_SHORT).show();
+        }
+        mSoundTriggerUtil.deleteSoundModelUsingManager(mModelUuid2);
+    }
+
+    /**
+     * Called when the user clicks the re-enroll button.
+     * 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);
+        if (soundModel == null) {
+            Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show();
+            return;
+        }
+        // Generate a fake model to push.
+        byte[] data = new byte[2048];
+        mRandom.nextBytes(data);
+        GenericSoundModel updated = new GenericSoundModel(soundModel.uuid,
+                soundModel.vendorUuid, data);
+        boolean status = mSoundTriggerUtil.addOrUpdateSoundModel(updated);
+        if (status) {
+            Toast.makeText(this, "Successfully re-enrolled, model UUID=" + updated.uuid,
+                    Toast.LENGTH_SHORT)
+                    .show();
+        } else {
+            Toast.makeText(this, "Failed to re-enroll!!!", Toast.LENGTH_SHORT).show();
+        }
+    }
+}
diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml
index fe17c6e..cbc6c76 100644
--- a/tests/VoiceInteraction/AndroidManifest.xml
+++ b/tests/VoiceInteraction/AndroidManifest.xml
@@ -61,5 +61,13 @@
                 <category android:name="android.intent.category.VOICE" />
             </intent-filter>
         </activity>
+        <activity android:name="StartVoiceInteractionActivity" android:label="In-Activity Voice"
+                  android:theme="@android:style/Theme.Material.Light">
+            <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/VoiceInteraction/res/layout/local_interaction_app.xml b/tests/VoiceInteraction/res/layout/local_interaction_app.xml
new file mode 100644
index 0000000..9694133
--- /dev/null
+++ b/tests/VoiceInteraction/res/layout/local_interaction_app.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:padding="8dp"
+    >
+
+    <TextView android:id="@+id/log"
+        android:layout_width="match_parent"
+        android:layout_height="0px"
+        android:layout_weight="1"
+        android:layout_marginTop="16dp"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        />
+
+    <LinearLayout android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/start"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/startFromActivity"
+            />
+
+    </LinearLayout>
+
+    <LinearLayout android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/stop"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/stopFromActivity"
+            android:enabled="false"
+            />
+
+    </LinearLayout>
+
+    <LinearLayout android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/command"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/commandVoice"
+            />
+
+        <Button android:id="@+id/pick"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/pickVoice"
+            />
+
+    </LinearLayout>
+
+    <LinearLayout android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:layout_marginBottom="16dp"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/cancelVoice"
+        />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml
index c665c23..64f8bc5 100644
--- a/tests/VoiceInteraction/res/values/strings.xml
+++ b/tests/VoiceInteraction/res/values/strings.xml
@@ -31,6 +31,8 @@
     <string name="pickVoice">Pick Voice</string>
     <string name="cancelVoice">Cancel</string>
     <string name="jumpOut">Jump out</string>
+    <string name="startFromActivity">Start voice interaction</string>
+    <string name="stopFromActivity">Stop voice interaction</string>
 
     <string name="largetext">This is a bunch of text that we will use to show how we handle it
 when reporting it for assist data.  We need many many lines of text, like\n
diff --git a/tests/VoiceInteraction/res/xml/interaction_service.xml b/tests/VoiceInteraction/res/xml/interaction_service.xml
index c015ad2..f0c88a2 100644
--- a/tests/VoiceInteraction/res/xml/interaction_service.xml
+++ b/tests/VoiceInteraction/res/xml/interaction_service.xml
@@ -21,4 +21,5 @@
     android:sessionService="com.android.test.voiceinteraction.MainInteractionSessionService"
     android:recognitionService="com.android.test.voiceinteraction.MainRecognitionService"
     android:settingsActivity="com.android.test.voiceinteraction.SettingsActivity"
-    android:supportsAssist="true" />
+    android:supportsAssist="true" 
+    android:supportsLocalInteraction="true" />
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 6e3694b..450334c 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -73,6 +73,7 @@
     CharSequence mPendingPrompt;
     Request mPendingRequest;
     int mCurrentTask = -1;
+    int mShowFlags;
 
     MainInteractionSession(Context context) {
         super(context);
@@ -88,6 +89,7 @@
     @Override
     public void onShow(Bundle args, int showFlags) {
         super.onShow(args, showFlags);
+        mShowFlags = showFlags;
         Log.i(TAG, "onShow: flags=0x" + Integer.toHexString(showFlags) + " args=" + args);
         mState = STATE_IDLE;
         mStartIntent = args != null ? (Intent)args.getParcelable("intent") : null;
@@ -311,6 +313,8 @@
         if (mState != STATE_IDLE) {
             outInsets.contentInsets.top = mBottomContent.getTop();
             outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_CONTENT;
+        } else if ((mShowFlags & SHOW_SOURCE_ACTIVITY) != 0) {
+            outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_CONTENT;
         }
     }
 
@@ -355,7 +359,7 @@
             mPendingPrompt = prompt.getVisualPrompt();
         }
     }
-      
+
     @Override
     public void onRequestConfirmation(ConfirmationRequest request) {
         Log.i(TAG, "onConfirm: prompt=" + request.getVoicePrompt() + " extras="
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java
new file mode 100644
index 0000000..41058c9
--- /dev/null
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.voiceinteraction;
+
+import android.app.Activity;
+import android.app.VoiceInteractor;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class StartVoiceInteractionActivity extends Activity implements View.OnClickListener {
+    static final String TAG = "LocalVoiceInteractionActivity";
+
+    static final String REQUEST_ABORT = "abort";
+    static final String REQUEST_COMPLETE = "complete";
+    static final String REQUEST_COMMAND = "command";
+    static final String REQUEST_PICK = "pick";
+    static final String REQUEST_CONFIRM = "confirm";
+
+    VoiceInteractor mInteractor;
+    VoiceInteractor.Request mCurrentRequest = null;
+    TextView mLog;
+    Button mCommandButton;
+    Button mPickButton;
+    Button mCancelButton;
+    Button mStartButton;
+    Button mStopButton;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.local_interaction_app);
+
+        mLog = (TextView)findViewById(R.id.log);
+        mCommandButton = (Button)findViewById(R.id.command);
+        mCommandButton.setOnClickListener(this);
+        mPickButton = (Button)findViewById(R.id.pick);
+        mPickButton.setOnClickListener(this);
+        mCancelButton = (Button)findViewById(R.id.cancel);
+        mCancelButton.setOnClickListener(this);
+        mStartButton = (Button) findViewById(R.id.start);
+        mStartButton.setOnClickListener(this);
+        mStopButton = (Button) findViewById(R.id.stop);
+        mStopButton.setOnClickListener(this);
+
+        mLog.append("Local Voice Interaction Supported = " + isLocalVoiceInteractionSupported());
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v == mCommandButton) {
+            VoiceInteractor.CommandRequest req = new TestCommand("Some arg");
+            mInteractor.submitRequest(req, REQUEST_COMMAND);
+        } else if (v == mPickButton) {
+            VoiceInteractor.PickOptionRequest.Option[] options =
+                    new VoiceInteractor.PickOptionRequest.Option[5];
+            options[0] = new VoiceInteractor.PickOptionRequest.Option("One");
+            options[1] = new VoiceInteractor.PickOptionRequest.Option("Two");
+            options[2] = new VoiceInteractor.PickOptionRequest.Option("Three");
+            options[3] = new VoiceInteractor.PickOptionRequest.Option("Four");
+            options[4] = new VoiceInteractor.PickOptionRequest.Option("Five");
+            VoiceInteractor.PickOptionRequest req = new TestPickOption(options);
+            mInteractor.submitRequest(req, REQUEST_PICK);
+        } else if (v == mCancelButton && mCurrentRequest != null) {
+            Log.i(TAG, "Cancel request");
+            mCurrentRequest.cancel();
+        } else if (v == mStartButton) {
+            Bundle args = new Bundle();
+            args.putString("Foo", "Bar");
+            startLocalVoiceInteraction(args);
+        } else if (v == mStopButton) {
+            stopLocalVoiceInteraction();
+        }
+    }
+
+    @Override
+    public void onLocalVoiceInteractionStarted() {
+        mInteractor = getVoiceInteractor();
+        mLog.append("\nLocalVoiceInteraction started!");
+        mStopButton.setEnabled(true);
+    }
+
+    @Override
+    public void onLocalVoiceInteractionStopped() {
+        mInteractor = getVoiceInteractor();
+        mLog.append("\nLocalVoiceInteraction stopped!");
+        mStopButton.setEnabled(false);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    static class TestAbortVoice extends VoiceInteractor.AbortVoiceRequest {
+        public TestAbortVoice() {
+            super(new VoiceInteractor.Prompt("Dammit, we suck :("), null);
+        }
+        @Override public void onCancel() {
+            Log.i(TAG, "Canceled!");
+            ((StartVoiceInteractionActivity)getActivity()).mLog.append("Canceled abort\n");
+        }
+        @Override public void onAbortResult(Bundle result) {
+            Log.i(TAG, "Abort result: result=" + result);
+            ((StartVoiceInteractionActivity)getActivity()).mLog.append(
+                    "Abort: result=" + result + "\n");
+            getActivity().finish();
+        }
+    }
+
+    static class TestCompleteVoice extends VoiceInteractor.CompleteVoiceRequest {
+        public TestCompleteVoice() {
+            super(new VoiceInteractor.Prompt("Woohoo, completed!"), null);
+        }
+        @Override public void onCancel() {
+            Log.i(TAG, "Canceled!");
+            ((StartVoiceInteractionActivity)getActivity()).mLog.append("Canceled complete\n");
+        }
+        @Override public void onCompleteResult(Bundle result) {
+            Log.i(TAG, "Complete result: result=" + result);
+            ((StartVoiceInteractionActivity)getActivity()).mLog.append("Complete: result="
+                    + result + "\n");
+            getActivity().finish();
+        }
+    }
+
+    static class TestCommand extends VoiceInteractor.CommandRequest {
+        public TestCommand(String arg) {
+            super("com.android.test.voiceinteraction.COMMAND", makeBundle(arg));
+        }
+        @Override public void onCancel() {
+            Log.i(TAG, "Canceled!");
+            ((StartVoiceInteractionActivity)getActivity()).mLog.append("Canceled command\n");
+        }
+        @Override
+        public void onCommandResult(boolean finished, Bundle result) {
+            Log.i(TAG, "Command result: finished=" + finished + " result=" + result);
+            StringBuilder sb = new StringBuilder();
+            if (finished) {
+                sb.append("Command final result: ");
+            } else {
+                sb.append("Command intermediate result: ");
+            }
+            if (result != null) {
+                result.getString("key");
+            }
+            sb.append(result);
+            sb.append("\n");
+            ((StartVoiceInteractionActivity)getActivity()).mLog.append(sb.toString());
+        }
+        static Bundle makeBundle(String arg) {
+            Bundle b = new Bundle();
+            b.putString("key", arg);
+            return b;
+        }
+    }
+
+    static class TestPickOption extends VoiceInteractor.PickOptionRequest {
+        public TestPickOption(Option[] options) {
+            super(new VoiceInteractor.Prompt("Need to pick something"), options, null);
+        }
+        @Override public void onCancel() {
+            Log.i(TAG, "Canceled!");
+            ((StartVoiceInteractionActivity)getActivity()).mLog.append("Canceled pick\n");
+        }
+        @Override
+        public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
+            Log.i(TAG, "Pick result: finished=" + finished + " selections=" + selections
+                    + " result=" + result);
+            StringBuilder sb = new StringBuilder();
+            if (finished) {
+                sb.append("Pick final result: ");
+            } else {
+                sb.append("Pick intermediate result: ");
+            }
+            for (int i=0; i<selections.length; i++) {
+                if (i >= 1) {
+                    sb.append(", ");
+                }
+                sb.append(selections[i].getLabel());
+            }
+            sb.append("\n");
+            ((StartVoiceInteractionActivity)getActivity()).mLog.append(sb.toString());
+        }
+    }
+}
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index f3a9ea3..3ecb2c4 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -907,6 +907,8 @@
     Maybe<std::string> versionCode, versionName;
     Maybe<std::string> customJavaPackage;
     std::vector<std::string> extraJavaPackages;
+    bool legacyXFlag = false;
+    bool requireLocalization = false;
     Flags flags = Flags()
             .requiredFlag("-o", "Output path", &options.outputPath)
             .requiredFlag("--manifest", "Path to the Android manifest to build",
@@ -922,6 +924,10 @@
             .optionalSwitch("--no-auto-version",
                             "Disables automatic style and layout SDK versioning",
                             &options.noAutoVersion)
+            .optionalSwitch("-x", "Legacy flag that specifies to use the package identifier 0x01",
+                            &legacyXFlag)
+            .optionalSwitch("-z", "Require localization of strings marked 'suggested'",
+                            &requireLocalization)
             .optionalSwitch("--output-to-dir", "Outputs the APK contents to a directory specified "
                             "by -o",
                             &options.outputToDirectory)
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 48012db..a3f3821 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -87,6 +87,11 @@
     }
 
     @Override
+    public void updatePointerIcon(float x, float y) {
+        // pass for now
+    }
+
+    @Override
     public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
             int localValue, int localChanges) {
         // pass for now.
@@ -105,4 +110,5 @@
         // pass for now.
         return null;
     }
+
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index 769285f..7b8e29a 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
@@ -148,7 +148,7 @@
 
     @Override
     public boolean performDrag(IWindow window, IBinder dragToken,
-            float touchX, float touchY, float thumbCenterX, float thumbCenterY,
+            int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
             ClipData data)
             throws RemoteException {
         // pass for now
diff --git a/tools/layoutlib/bridge/src/libcore/util/ZoneInfo_WallTime_Delegate.java b/tools/layoutlib/bridge/src/libcore/util/ZoneInfo_WallTime_Delegate.java
deleted file mode 100644
index f29c5c0..0000000
--- a/tools/layoutlib/bridge/src/libcore/util/ZoneInfo_WallTime_Delegate.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.GregorianCalendar;
-
-/**
- * Delegate used to provide alternate implementation of select methods in {@link ZoneInfo.WallTime}
- */
-public class ZoneInfo_WallTime_Delegate {
-
-    @LayoutlibDelegate
-    static GregorianCalendar createGregorianCalendar() {
-        return new GregorianCalendar();
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 87f6106..d106592 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -224,7 +224,6 @@
         "libcore.io.MemoryMappedFile#mmapRO",
         "libcore.io.MemoryMappedFile#close",
         "libcore.io.MemoryMappedFile#bigEndianIterator",
-        "libcore.util.ZoneInfo$WallTime#createGregorianCalendar",
     };
 
     /**
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 6e42391..605e8c0 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -15,12 +15,14 @@
  */
 package android.net.wifi;
 
+import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.security.Credentials;
 import android.text.TextUtils;
 
 import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
 import java.security.KeyFactory;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
@@ -72,6 +74,13 @@
     public static final String KEYSTORE_URI = "keystore://";
 
     /**
+     * String representing the keystore URI used for wpa_supplicant,
+     * Unlike #KEYSTORE_URI, this supports a list of space-delimited aliases
+     * @hide
+     */
+    public static final String KEYSTORES_URI = "keystores://";
+
+    /**
      * String to set the engine value to when it should be enabled.
      * @hide
      */
@@ -101,10 +110,12 @@
     public static final String REALM_KEY           = "realm";
     /** @hide */
     public static final String PLMN_KEY            = "plmn";
+    /** @hide */
+    public static final String CA_CERT_ALIAS_DELIMITER = " ";
 
 
     private HashMap<String, String> mFields = new HashMap<String, String>();
-    private X509Certificate mCaCert;
+    private X509Certificate[] mCaCerts;
     private PrivateKey mClientPrivateKey;
     private X509Certificate mClientCertificate;
 
@@ -136,7 +147,7 @@
             dest.writeString(entry.getValue());
         }
 
-        writeCertificate(dest, mCaCert);
+        writeCertificates(dest, mCaCerts);
 
         if (mClientPrivateKey != null) {
             String algorithm = mClientPrivateKey.getAlgorithm();
@@ -151,6 +162,17 @@
         writeCertificate(dest, mClientCertificate);
     }
 
+    private void writeCertificates(Parcel dest, X509Certificate[] cert) {
+        if (cert != null && cert.length != 0) {
+            dest.writeInt(cert.length);
+            for (int i = 0; i < cert.length; i++) {
+                writeCertificate(dest, cert[i]);
+            }
+        } else {
+            dest.writeInt(0);
+        }
+    }
+
     private void writeCertificate(Parcel dest, X509Certificate cert) {
         if (cert != null) {
             try {
@@ -176,7 +198,7 @@
                         enterpriseConfig.mFields.put(key, value);
                     }
 
-                    enterpriseConfig.mCaCert = readCertificate(in);
+                    enterpriseConfig.mCaCerts = readCertificates(in);
 
                     PrivateKey userKey = null;
                     int len = in.readInt();
@@ -199,6 +221,18 @@
                     return enterpriseConfig;
                 }
 
+                private X509Certificate[] readCertificates(Parcel in) {
+                    X509Certificate[] certs = null;
+                    int len = in.readInt();
+                    if (len > 0) {
+                        certs = new X509Certificate[len];
+                        for (int i = 0; i < len; i++) {
+                            certs[i] = readCertificate(in);
+                        }
+                    }
+                    return certs;
+                }
+
                 private X509Certificate readCertificate(Parcel in) {
                     X509Certificate cert = null;
                     int len = in.readInt();
@@ -399,6 +433,36 @@
     }
 
     /**
+     * Encode a CA certificate alias so it does not contain illegal character.
+     * @hide
+     */
+    public static String encodeCaCertificateAlias(String alias) {
+        byte[] bytes = alias.getBytes(StandardCharsets.UTF_8);
+        StringBuilder sb = new StringBuilder(bytes.length * 2);
+        for (byte o : bytes) {
+            sb.append(String.format("%02x", o & 0xFF));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Decode a previously-encoded CA certificate alias.
+     * @hide
+     */
+    public static String decodeCaCertificateAlias(String alias) {
+        byte[] data = new byte[alias.length() >> 1];
+        for (int n = 0, position = 0; n < alias.length(); n += 2, position++) {
+            data[position] = (byte) Integer.parseInt(alias.substring(n,  n + 2), 16);
+        }
+        try {
+            return new String(data, StandardCharsets.UTF_8);
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+            return alias;
+        }
+    }
+
+    /**
      * Set CA certificate alias.
      *
      * <p> See the {@link android.security.KeyChain} for details on installing or choosing
@@ -412,6 +476,35 @@
     }
 
     /**
+     * Set CA certificate aliases. When creating installing the corresponding certificate to
+     * the keystore, please use alias encoded by {@link #encodeCaCertificateAlias(String)}.
+     *
+     * <p> See the {@link android.security.KeyChain} for details on installing or choosing
+     * a certificate.
+     * </p>
+     * @param aliases identifies the certificate
+     * @hide
+     */
+    public void setCaCertificateAliases(@Nullable String[] aliases) {
+        if (aliases == null) {
+            setFieldValue(CA_CERT_KEY, null, CA_CERT_PREFIX);
+        } else if (aliases.length == 1) {
+            // Backwards compatibility: use the original cert prefix if setting only one alias.
+            setCaCertificateAlias(aliases[0]);
+        } else {
+            // Use KEYSTORES_URI which supports multiple aliases.
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < aliases.length; i++) {
+                if (i > 0) {
+                    sb.append(CA_CERT_ALIAS_DELIMITER);
+                }
+                sb.append(encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + aliases[i]));
+            }
+            setFieldValue(CA_CERT_KEY, sb.toString(), KEYSTORES_URI);
+        }
+    }
+
+    /**
      * Get CA certificate alias
      * @return alias to the CA certificate
      * @hide
@@ -421,6 +514,32 @@
     }
 
     /**
+     * Get CA certificate aliases
+     * @return alias to the CA certificate
+     * @hide
+     */
+    @Nullable public String[] getCaCertificateAliases() {
+        String value = getFieldValue(CA_CERT_KEY, "");
+        if (value.startsWith(CA_CERT_PREFIX)) {
+            // Backwards compatibility: parse the original alias prefix.
+            return new String[] {getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX)};
+        } else if (value.startsWith(KEYSTORES_URI)) {
+            String values = value.substring(KEYSTORES_URI.length());
+
+            String[] aliases = TextUtils.split(values, CA_CERT_ALIAS_DELIMITER);
+            for (int i = 0; i < aliases.length; i++) {
+                aliases[i] = decodeCaCertificateAlias(aliases[i]);
+                if (aliases[i].startsWith(Credentials.CA_CERTIFICATE)) {
+                    aliases[i] = aliases[i].substring(Credentials.CA_CERTIFICATE.length());
+                }
+            }
+            return aliases.length != 0 ? aliases : null;
+        } else {
+            return TextUtils.isEmpty(value) ? null : new String[] {value};
+        }
+    }
+
+    /**
      * Specify a X.509 certificate that identifies the server.
      *
      * <p>A default name is automatically assigned to the certificate and used
@@ -431,31 +550,76 @@
      * @param cert X.509 CA certificate
      * @throws IllegalArgumentException if not a CA certificate
      */
-    public void setCaCertificate(X509Certificate cert) {
+    public void setCaCertificate(@Nullable X509Certificate cert) {
         if (cert != null) {
             if (cert.getBasicConstraints() >= 0) {
-                mCaCert = cert;
+                mCaCerts = new X509Certificate[] {cert};
             } else {
                 throw new IllegalArgumentException("Not a CA certificate");
             }
         } else {
-            mCaCert = null;
+            mCaCerts = null;
         }
     }
 
     /**
-     * Get CA certificate
+     * Get CA certificate. If multiple CA certificates are configured previously,
+     * return the first one.
      * @return X.509 CA certificate
      */
-    public X509Certificate getCaCertificate() {
-        return mCaCert;
+    @Nullable public X509Certificate getCaCertificate() {
+        if (mCaCerts != null && mCaCerts.length > 0) {
+            return mCaCerts[0];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Specify a list of X.509 certificates that identifies the server. The validation
+     * passes if the CA of server certificate matches one of the given certificates.
+
+     * <p>Default names are automatically assigned to the certificates and used
+     * with this configuration. The framework takes care of installing the
+     * certificates when the config is saved and removing the certificates when
+     * the config is removed.
+     *
+     * @param certs X.509 CA certificates
+     * @throws IllegalArgumentException if any of the provided certificates is
+     *     not a CA certificate
+     */
+    public void setCaCertificates(@Nullable X509Certificate[] certs) {
+        if (certs != null) {
+            X509Certificate[] newCerts = new X509Certificate[certs.length];
+            for (int i = 0; i < certs.length; i++) {
+                if (certs[i].getBasicConstraints() >= 0) {
+                    newCerts[i] = certs[i];
+                } else {
+                    throw new IllegalArgumentException("Not a CA certificate");
+                }
+            }
+            mCaCerts = newCerts;
+        } else {
+            mCaCerts = null;
+        }
+    }
+
+    /**
+     * Get CA certificates.
+     */
+    @Nullable public X509Certificate[] getCaCertificates() {
+        if (mCaCerts != null || mCaCerts.length > 0) {
+            return mCaCerts;
+        } else {
+            return null;
+        }
     }
 
     /**
      * @hide
      */
     public void resetCaCertificate() {
-        mCaCert = null;
+        mCaCerts = null;
     }
 
     /** Set Client certificate alias.
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 76c679c..44be671 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -136,17 +136,29 @@
         }
     }
 
-    /** reports {@link ScanListener#onResults} when underlying buffers are full
+    /**
+     * reports {@link ScanListener#onResults} when underlying buffers are full
+     * this is simply the lack of the {@link #REPORT_EVENT_AFTER_EACH_SCAN} flag
      * @deprecated
      */
     @Deprecated
     public static final int REPORT_EVENT_AFTER_BUFFER_FULL = 0;
-    /** reports {@link ScanListener#onResults} after each scan */
-    public static final int REPORT_EVENT_AFTER_EACH_SCAN = 1;
-    /** reports {@link ScanListener#onFullResult} whenever each beacon is discovered */
-    public static final int REPORT_EVENT_FULL_SCAN_RESULT = 2;
-    /** do not batch */
-    public static final int REPORT_EVENT_NO_BATCH = 4;
+    /**
+     * reports {@link ScanListener#onResults} after each scan
+     */
+    public static final int REPORT_EVENT_AFTER_EACH_SCAN = (1 << 0);
+    /**
+     * reports {@link ScanListener#onFullResult} whenever each beacon is discovered
+     */
+    public static final int REPORT_EVENT_FULL_SCAN_RESULT = (1 << 1);
+    /**
+     * 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/passpoint/IWifiPasspointManager.aidl b/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl
deleted file mode 100644
index 50bec33..0000000
--- a/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-import android.net.wifi.ScanResult;
-import android.net.wifi.passpoint.WifiPasspointPolicy;
-import android.net.wifi.passpoint.WifiPasspointCredential;
-import android.os.Messenger;
-
-/**
- * Interface that allows controlling and querying Wifi Passpoint connectivity.
- *
- * {@hide}
- */
-interface IWifiPasspointManager
-{
-    Messenger getMessenger();
-
-    int getPasspointState();
-
-    List<WifiPasspointPolicy> requestCredentialMatch(in List<ScanResult> requested);
-
-    List<WifiPasspointCredential> getCredentials();
-
-    boolean addCredential(in WifiPasspointCredential cred);
-
-    boolean updateCredential(in WifiPasspointCredential cred);
-
-    boolean removeCredential(in WifiPasspointCredential cred);
-}
-
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl
deleted file mode 100644
index cfd3605..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-parcelable WifiPasspointCredential;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java
deleted file mode 100644
index a100aed..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-import android.net.wifi.WifiEnterpriseConfig;
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * A class representing a Wi-Fi Passpoint credential.
- * @hide
- */
-public class WifiPasspointCredential implements Parcelable {
-
-    private final static String TAG = "PasspointCredential";
-    private final static boolean DBG = true;
-
-    /** Wi-Fi nodes**/
-    private String mWifiSpFqdn;
-
-    /** PerProviderSubscription nodes **/
-    private String mCredentialName;
-
-    /** SubscriptionUpdate nodes **/
-    private String mSubscriptionUpdateInterval;
-    private String mSubscriptionUpdateMethod;
-    private String mSubscriptionUpdateRestriction;
-    private String mSubscriptionUpdateURI;
-    private String mSubscriptionUpdateUsername;
-    private String mSubscriptionUpdatePassword;
-
-    /** HomeSP nodes **/
-    private String mHomeSpFqdn;
-    private String mFriendlyName;
-    private Collection<WifiPasspointDmTree.HomeOIList> mHomeOIList;
-    private Collection<WifiPasspointDmTree.OtherHomePartners> mOtherHomePartnerList;
-
-    /** SubscriptionParameters nodes**/
-    private String mCreationDate;
-    private String mExpirationDate;
-
-    /** Credential nodes **/
-    private String mType;
-    private String mInnerMethod;
-    private String mCertType;
-    private String mCertSha256Fingerprint;
-    private String mUpdateIdentifier;
-    private String mUsername;
-    private String mPasswd;
-    private String mRealm;
-    private String mImsi;
-    private String mMcc;
-    private String mMnc;
-    private String mCaRootCert;
-    private String mClientCert;
-    private boolean mCheckAaaServerCertStatus;
-
-    /** Policy nodes **/
-    private String mPolicyUpdateUri;
-    private String mPolicyUpdateInterval;
-    private String mPolicyUpdateUsername;
-    private String mPolicyUpdatePassword;
-    private String mPolicyUpdateRestriction;
-    private String mPolicyUpdateMethod;
-    private Collection<WifiPasspointDmTree.PreferredRoamingPartnerList> mPreferredRoamingPartnerList;
-    private Collection<WifiPasspointDmTree.MinBackhaulThresholdNetwork> mMinBackhaulThresholdNetwork;
-    private Collection<WifiPasspointDmTree.SPExclusionList> mSpExclusionList;
-    private Collection<WifiPasspointDmTree.RequiredProtoPortTuple> mRequiredProtoPortTuple;
-    private String mMaxBssLoad;
-
-    /** CrednetialPriority node **/
-    private int mCrednetialPriority;
-
-    /** AAAServerTrustRoot nodes **/
-    private String mAaaCertUrl;
-    private String mAaaSha256Fingerprint;
-
-    /** Others **/
-    private boolean mIsMachineRemediation;
-    private boolean mUserPreferred = false;
-    private String mWifiTreePath;
-    private WifiEnterpriseConfig mEnterpriseConfig;
-
-    /** @hide */
-    public WifiPasspointCredential() {}
-
-    /**
-     * Constructor
-     * @param realm Realm of the passpoint credential
-     * @param fqdn Fully qualified domain name (FQDN) of the credential
-     * @param config Enterprise config, must be either EAP-TLS or EAP-TTLS
-     * @see WifiEnterpriseConfig
-     */
-    public WifiPasspointCredential(String realm, String fqdn, WifiEnterpriseConfig config) {
-        mRealm = realm;
-        switch (config.getEapMethod()) {
-            case WifiEnterpriseConfig.Eap.TLS:
-            case WifiEnterpriseConfig.Eap.TTLS:
-                mEnterpriseConfig = new WifiEnterpriseConfig(config);
-                break;
-            default:
-                // ignore
-        }
-    }
-
-    /** @hide */
-    public WifiPasspointCredential(String type,
-            String caroot,
-            String clientcert,
-            String mcc,
-            String mnc,
-            WifiPasspointDmTree.SpFqdn sp,
-            WifiPasspointDmTree.CredentialInfo credinfo) {
-
-        if (credinfo == null) {
-            return;
-        }
-
-        mType = type;
-        mCaRootCert = caroot;
-        mClientCert = clientcert;
-
-        mWifiSpFqdn = sp.nodeName;
-        mUpdateIdentifier = sp.perProviderSubscription.UpdateIdentifier;
-
-        mCredentialName = credinfo.nodeName;
-        mOtherHomePartnerList = credinfo.homeSP.otherHomePartners.values();
-
-        Set set = credinfo.aAAServerTrustRoot.entrySet();
-        Iterator i = set.iterator();
-        if (i.hasNext()) {
-            Map.Entry entry3 = (Map.Entry) i.next();
-            WifiPasspointDmTree.AAAServerTrustRoot aaa = (WifiPasspointDmTree.AAAServerTrustRoot) entry3.getValue();
-            mAaaCertUrl = aaa.CertURL;
-            mAaaSha256Fingerprint = aaa.CertSHA256Fingerprint;
-        }
-
-        mCertType = credinfo.credential.digitalCertificate.CertificateType;
-        mCertSha256Fingerprint = credinfo.credential.digitalCertificate.CertSHA256Fingerprint;
-        mUsername = credinfo.credential.usernamePassword.Username;
-        mPasswd = credinfo.credential.usernamePassword.Password;
-        mIsMachineRemediation = credinfo.credential.usernamePassword.MachineManaged;
-        mInnerMethod = credinfo.credential.usernamePassword.eAPMethod.InnerMethod;
-        mImsi = credinfo.credential.sim.IMSI;
-        mMcc = mcc;
-        mMnc = mnc;
-        mCreationDate = credinfo.credential.CreationDate;
-        mExpirationDate = credinfo.credential.ExpirationDate;
-        mRealm = credinfo.credential.Realm;
-
-        if (credinfo.credentialPriority == null) {
-            mCrednetialPriority = 128;
-        } else {
-            mCrednetialPriority = Integer.parseInt(credinfo.credentialPriority);
-        }
-
-        mHomeSpFqdn = credinfo.homeSP.FQDN;
-
-        mSubscriptionUpdateInterval = credinfo.subscriptionUpdate.UpdateInterval;
-        mSubscriptionUpdateMethod = credinfo.subscriptionUpdate.UpdateMethod;
-        mSubscriptionUpdateRestriction = credinfo.subscriptionUpdate.Restriction;
-        mSubscriptionUpdateURI = credinfo.subscriptionUpdate.URI;
-        mSubscriptionUpdateUsername = credinfo.subscriptionUpdate.usernamePassword.Username;
-        mSubscriptionUpdatePassword = credinfo.subscriptionUpdate.usernamePassword.Password;
-
-        mPolicyUpdateUri = credinfo.policy.policyUpdate.URI;
-        mPolicyUpdateInterval = credinfo.policy.policyUpdate.UpdateInterval;
-        mPolicyUpdateUsername = credinfo.policy.policyUpdate.usernamePassword.Username;
-        mPolicyUpdatePassword = credinfo.policy.policyUpdate.usernamePassword.Password;
-        mPolicyUpdateRestriction = credinfo.policy.policyUpdate.Restriction;
-        mPolicyUpdateMethod = credinfo.policy.policyUpdate.UpdateMethod;
-        mPreferredRoamingPartnerList = credinfo.policy.preferredRoamingPartnerList.values();
-        mMinBackhaulThresholdNetwork = credinfo.policy.minBackhaulThreshold.values();
-        mRequiredProtoPortTuple = credinfo.policy.requiredProtoPortTuple.values();
-        mMaxBssLoad = credinfo.policy.maximumBSSLoadValue;
-        mSpExclusionList = credinfo.policy.sPExclusionList.values();
-
-        mHomeOIList = credinfo.homeSP.homeOIList.values();
-        mFriendlyName = credinfo.homeSP.FriendlyName;
-        mCheckAaaServerCertStatus = credinfo.credential.CheckAAAServerCertStatus;
-    }
-
-    /** @hide */
-    public String getUpdateIdentifier() {
-        return mUpdateIdentifier;
-    }
-
-    /** @hide */
-    public String getUpdateMethod() {
-        return mSubscriptionUpdateMethod;
-    }
-
-    /** @hide */
-    public void setUpdateMethod(String method) {
-        mSubscriptionUpdateMethod = method;
-    }
-
-    /** @hide */
-    public String getWifiSpFqdn() {
-        return mWifiSpFqdn;
-    }
-
-    /** @hide */
-    public String getCredName() {
-        return mCredentialName;
-    }
-
-    /** @hide */
-    public String getType() {
-        return mType;
-    }
-
-    /**
-     * Get enterprise config of this Passpoint credential.
-     * @return Enterprise config
-     * @see WifiEnterpriseConfig
-     */
-    public WifiEnterpriseConfig getEnterpriseConfig() {
-        return new WifiEnterpriseConfig(mEnterpriseConfig);
-    }
-
-    /**
-     * Set enterprise config of this Passpoint credential.
-     * @param config Enterprise config, must be either EAP-TLS or EAP-TTLS
-     * @see WifiEnterpriseConfig
-     */
-    public void setEnterpriseConfig(WifiEnterpriseConfig config) {
-        // TODO
-    }
-
-    /** @hide */
-    public String getCertType() {
-        return mCertType;
-    }
-
-    /** @hide */
-    public String getCertSha256Fingerprint() {
-        return mCertSha256Fingerprint;
-    }
-
-    /** @hide */
-    public String getUserName() {
-        return mUsername;
-    }
-
-    /** @hide */
-    public String getPassword() {
-        // TODO: guarded by connectivity internal
-        return mPasswd;
-    }
-
-    /** @hide */
-    public String getImsi() {
-        return mImsi;
-    }
-
-    /** @hide */
-    public String getMcc() {
-        return mMcc;
-    }
-
-    /** @hide */
-    public String getMnc() {
-        return mMnc;
-    }
-
-    /** @hide */
-    public String getCaRootCertPath() {
-        return mCaRootCert;
-    }
-
-    /** @hide */
-    public String getClientCertPath() {
-        return mClientCert;
-    }
-
-    /**
-     * Get the realm of this Passpoint credential.
-     * @return Realm
-     */
-    public String getRealm() {
-        return mRealm;
-    }
-
-    /**
-     * Set the ream of this Passpoint credential.
-     * @param realm Realm
-     */
-    public void setRealm(String realm) {
-        mRealm = realm;
-    }
-
-    /** @hide */
-    public int getPriority() {
-        if (mUserPreferred) {
-            return 0;
-        }
-
-        return mCrednetialPriority;
-    }
-
-    /**
-     * Get the fully qualified domain name (FQDN) of this Passpoint credential.
-     * @return FQDN
-     */
-    public String getHomeSpFqdn() {
-        return mHomeSpFqdn;
-    }
-
-    /**
-     * Set the fully qualified domain name (FQDN) of this Passpoint credential.
-     * @param fqdn FQDN
-     */
-    public void setHomeFqdn(String fqdn) {
-        mHomeSpFqdn = fqdn;
-    }
-
-
-    /** @hide */
-    public Collection<WifiPasspointDmTree.OtherHomePartners> getOtherHomePartnerList() {
-        return mOtherHomePartnerList;
-    }
-
-    /** @hide */
-    public String getSubscriptionUpdateUsername() {
-        return mSubscriptionUpdateUsername;
-    }
-
-    /** @hide */
-    public String getSubscriptionUpdatePassword() {
-        return mSubscriptionUpdatePassword;
-    }
-
-    /** @hide */
-    public String getPolicyUpdateUri() {
-        return mPolicyUpdateUri;
-    }
-
-    /** @hide */
-    public String getPolicyUpdateInterval() {
-        return mPolicyUpdateInterval;
-    }
-
-    /** @hide */
-    public String getPolicyUpdateUsername() {
-        return mPolicyUpdateUsername;
-    }
-
-    /** @hide */
-    public String getPolicyUpdatePassword() {
-        return mPolicyUpdatePassword;
-    }
-
-    /** @hide */
-    public String getPolicyUpdateRestriction() {
-        return mPolicyUpdateRestriction;
-    }
-
-    /** @hide */
-    public String getPolicyUpdateMethod() {
-        return mPolicyUpdateMethod;
-    }
-
-    /** @hide */
-    public String getCreationDate() {
-        return mCreationDate;
-    }
-
-    /** @hide */
-    public String getExpirationDate() {
-        return mExpirationDate;
-    }
-
-    /** @hide */
-    public void setExpirationDate(String expirationdate) {
-        mExpirationDate = expirationdate;
-    }
-
-    /** @hide */
-    public Collection<WifiPasspointDmTree.PreferredRoamingPartnerList> getPreferredRoamingPartnerList() {
-        return mPreferredRoamingPartnerList;
-    }
-
-    /** @hide */
-    public Collection<WifiPasspointDmTree.HomeOIList> getHomeOiList() {
-        return mHomeOIList;
-    }
-
-    /** @hide */
-    public Collection<WifiPasspointDmTree.MinBackhaulThresholdNetwork> getBackhaulThresholdList() {
-        return mMinBackhaulThresholdNetwork;
-    }
-
-    /** @hide */
-    public Collection<WifiPasspointDmTree.RequiredProtoPortTuple> getRequiredProtoPortList() {
-        return mRequiredProtoPortTuple;
-    }
-
-    /** @hide */
-    public Collection<WifiPasspointDmTree.SPExclusionList> getSPExclusionList() {
-        return mSpExclusionList;
-    }
-
-    /** @hide */
-    public boolean getIsMachineRemediation() {
-        return mIsMachineRemediation;
-    }
-
-    /** @hide */
-    public String getAaaCertUrl() {
-        return mAaaCertUrl;
-    }
-
-    /** @hide */
-    public String getAaaSha256Fingerprint() {
-        return mAaaSha256Fingerprint;
-    }
-
-    /** @hide */
-    public String getSubscriptionUpdateRestriction() {
-        return mSubscriptionUpdateRestriction;
-    }
-
-    /** @hide */
-    public String getSubscriptionUpdateURI() {
-        return mSubscriptionUpdateURI;
-    }
-
-    /** @hide */
-    public String getSubscriptionUpdateInterval() {
-        return mSubscriptionUpdateInterval;
-    }
-
-    /** @hide */
-    public String getFriendlyName() {
-        return mFriendlyName;
-    }
-
-    /** @hide */
-    public String getMaxBssLoad() {
-        return mMaxBssLoad;
-    }
-
-    /** @hide */
-    public boolean getUserPreference() {
-        return mUserPreferred;
-    }
-
-    /** @hide */
-    public boolean getCheckAaaServerCertStatus() {
-        return mCheckAaaServerCertStatus;
-    }
-
-    /** @hide */
-    public void setUserPreference(boolean value) {
-        mUserPreferred = value;
-    }
-
-    @Override
-    /** @hide */
-    public boolean equals(Object obj) {
-        boolean result = false;
-        if (obj instanceof WifiPasspointCredential) {
-            final WifiPasspointCredential other = (WifiPasspointCredential) obj;
-            if (this.mType.equals(other.mType)) {
-                if (this.mType.equals("TTLS")) {
-                    result = this.mUsername.equals(other.mUsername) &&
-                            this.mPasswd.equals(other.mPasswd) &&
-                            this.mRealm.equals(other.mRealm) &&
-                            this.mHomeSpFqdn.equals(other.mHomeSpFqdn);
-                }
-                if (this.mType.equals("TLS")) {
-                    result = this.mRealm.equals(other.mRealm) &&
-                            this.mHomeSpFqdn.equals(other.mHomeSpFqdn) &&
-                            this.mClientCert.equals(other.mClientCert);
-                }
-                if (this.mType.equals("SIM")) {
-                    result = this.mMcc.equals(other.mMcc) &&
-                            this.mMnc.equals(other.mMnc) &&
-                            this.mImsi.equals(other.mImsi) &&
-                            this.mHomeSpFqdn.equals(other.mHomeSpFqdn);
-                }
-            }
-        }
-        return result;
-    }
-
-    @Override
-    /** @hide */
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        String none = "<none>";
-
-        if (!DBG) {
-            sb.append(none);
-        } else {
-            sb.append(", UpdateIdentifier: ")
-            .append(mUpdateIdentifier == null ? none : mUpdateIdentifier)
-            .append(", SubscriptionUpdateMethod: ")
-            .append(mSubscriptionUpdateMethod == null ? none : mSubscriptionUpdateMethod)
-            .append(", Type: ").append(mType == null ? none : mType)
-            .append(", Username: ").append(mUsername == null ? none : mUsername)
-            .append(", Passwd: ").append(mPasswd == null ? none : mPasswd)
-            .append(", SubDMAccUsername: ")
-            .append(mSubscriptionUpdateUsername == null ? none : mSubscriptionUpdateUsername)
-            .append(", SubDMAccPassword: ")
-            .append(mSubscriptionUpdatePassword == null ? none : mSubscriptionUpdatePassword)
-            .append(", PolDMAccUsername: ")
-            .append(mPolicyUpdateUsername == null ? none : mPolicyUpdateUsername)
-            .append(", PolDMAccPassword: ")
-            .append(mPolicyUpdatePassword == null ? none : mPolicyUpdatePassword)
-            .append(", Imsi: ").append(mImsi == null ? none : mImsi)
-            .append(", Mcc: ").append(mMcc == null ? none : mMcc)
-            .append(", Mnc: ").append(mMnc == null ? none : mMnc)
-            .append(", CaRootCert: ").append(mCaRootCert == null ? none : mCaRootCert)
-            .append(", Realm: ").append(mRealm == null ? none : mRealm)
-            .append(", Priority: ").append(mCrednetialPriority)
-            .append(", Fqdn: ").append(mHomeSpFqdn == null ? none : mHomeSpFqdn)
-            .append(", Otherhomepartners: ")
-            .append(mOtherHomePartnerList == null ? none : mOtherHomePartnerList)
-            .append(", ExpirationDate: ")
-            .append(mExpirationDate == null ? none : mExpirationDate)
-            .append(", MaxBssLoad: ").append(mMaxBssLoad == null ? none : mMaxBssLoad)
-            .append(", SPExclusionList: ").append(mSpExclusionList);
-
-            if (mPreferredRoamingPartnerList != null) {
-                sb.append("PreferredRoamingPartnerList:");
-                for (WifiPasspointDmTree.PreferredRoamingPartnerList prpListItem : mPreferredRoamingPartnerList) {
-                    sb.append("[fqdnmatch:").append(prpListItem.FQDN_Match).
-                            append(", priority:").append(prpListItem.Priority).
-                            append(", country:").append(prpListItem.Country).append("]");
-                }
-            }
-
-            if (mHomeOIList != null) {
-                sb.append("HomeOIList:");
-                for (WifiPasspointDmTree.HomeOIList HomeOIListItem : mHomeOIList) {
-                    sb.append("[HomeOI:").append(HomeOIListItem.HomeOI).
-                            append(", HomeOIRequired:").append(HomeOIListItem.HomeOIRequired).
-                            append("]");
-                }
-            }
-
-            if (mMinBackhaulThresholdNetwork != null) {
-                sb.append("BackHaulThreshold:");
-                for (WifiPasspointDmTree.MinBackhaulThresholdNetwork BhtListItem : mMinBackhaulThresholdNetwork) {
-                    sb.append("[networkType:").append(BhtListItem.NetworkType).
-                            append(", dlBandwidth:").append(BhtListItem.DLBandwidth).
-                            append(", ulBandwidth:").append(BhtListItem.ULBandwidth).
-                            append("]");
-                }
-            }
-
-            if (mRequiredProtoPortTuple != null) {
-                sb.append("WifiMORequiredProtoPortTupleList:");
-                for (WifiPasspointDmTree.RequiredProtoPortTuple RpptListItem : mRequiredProtoPortTuple) {
-                    sb.append("[IPProtocol:").append(RpptListItem.IPProtocol).
-                            append(", PortNumber:").append(RpptListItem.PortNumber).
-                            append("]");
-                }
-            }
-        }
-        return sb.toString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mWifiSpFqdn);
-        dest.writeString(mCredentialName);
-        dest.writeString(mType);
-        dest.writeInt(mCrednetialPriority);
-        dest.writeString(mHomeSpFqdn);
-        dest.writeString(mRealm);
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void readFromParcel(Parcel in) {
-        mWifiSpFqdn = in.readString();
-        mCredentialName = in.readString();
-        mType = in.readString();
-        mCrednetialPriority = in.readInt();
-        mHomeSpFqdn = in.readString();
-        mRealm = in.readString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public static final Creator<WifiPasspointCredential> CREATOR =
-            new Creator<WifiPasspointCredential>() {
-                public WifiPasspointCredential createFromParcel(Parcel in) {
-                    WifiPasspointCredential pc = new WifiPasspointCredential();
-                    pc.mWifiSpFqdn = in.readString();
-                    pc.mCredentialName = in.readString();
-                    pc.mType = in.readString();
-                    pc.mCrednetialPriority = in.readInt();
-                    pc.mHomeSpFqdn = in.readString();
-                    pc.mRealm = in.readString();
-                    return pc;
-                }
-
-                public WifiPasspointCredential[] newArray(int size) {
-                    return new WifiPasspointCredential[size];
-                }
-            };
-
-    /** @hide */
-    public int compareTo(WifiPasspointCredential another) {
-
-        //The smaller the higher
-        if (mCrednetialPriority < another.mCrednetialPriority) {
-            return -1;
-        } else if (mCrednetialPriority == another.mCrednetialPriority) {
-            return this.mType.compareTo(another.mType);
-        } else {
-            return 1;
-        }
-    }
-
-    @Override
-    /** @hide */
-    public int hashCode() {
-        int hash = 208;
-        if (mType != null) {
-            hash += mType.hashCode();
-        }
-        if (mRealm != null) {
-            hash += mRealm.hashCode();
-        }
-        if (mHomeSpFqdn != null) {
-            hash += mHomeSpFqdn.hashCode();
-        }
-        if (mUsername != null) {
-            hash += mUsername.hashCode();
-        }
-        if (mPasswd != null) {
-            hash += mPasswd.hashCode();
-        }
-
-        return hash;
-    }
-}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl
deleted file mode 100644
index 6a88b2e..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-parcelable WifiPasspointDmTree;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java
deleted file mode 100644
index 427c84c..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java
+++ /dev/null
@@ -1,1375 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-import java.util.HashMap;
-
-/**
- * Required Mobile Device Management Tree Structure
- *
- *                   +----------+
- *                   | ./(Root) |
- *                   +----+-----+
- *                        |
- *  +---------+           |         +---------+  +---------+
- *  | DevInfo |-----------+---------|  Wi-Fi  |--|SP FQDN* |
- *  +---------+           |         +---------+  +---------+
- *  +---------+           |                           |
- *  |DevDetail|-----------+                      +-----------------------+
- *  +---------+                                  |PerproviderSubscription|--<X>+
- *                                               +-----------------------+
- *
- * This class contains all nodes start from Wi-Fi
- * @hide
- **/
-public class WifiPasspointDmTree implements Parcelable {
-    private final static String TAG = "WifiTree";
-    public int PpsMoId;//plugfest used only
-    public HashMap<String, SpFqdn> spFqdn = new HashMap<String, SpFqdn>();//Maps.newHashMap();
-
-    public SpFqdn createSpFqdn(String name) {
-        SpFqdn obj = new SpFqdn(name);
-        spFqdn.put(name, obj);
-        return obj;
-    }
-
-    public static class SpFqdn implements Parcelable {
-        public String nodeName;
-        public PerProviderSubscription perProviderSubscription = new PerProviderSubscription();
-
-        public SpFqdn(String name) {
-            nodeName = name;
-        }
-
-        public SpFqdn() {
-        }
-
-        public SpFqdn(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeParcelable(perProviderSubscription, flags);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                perProviderSubscription = in.readParcelable(PerProviderSubscription.class
-                        .getClassLoader());
-            }
-        }
-
-        public static final Parcelable.Creator<SpFqdn> CREATOR = new Parcelable.Creator<SpFqdn>() {
-            public SpFqdn createFromParcel(Parcel in) {
-                return new SpFqdn(in);
-            }
-
-            public SpFqdn[] newArray(int size) {
-                return new SpFqdn[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription
-     **/
-    public static class PerProviderSubscription implements Parcelable {
-        /**
-         * PerProviderSubscription/UpdateIdentifier
-         **/
-        public String UpdateIdentifier;
-        public HashMap<String, CredentialInfo> credentialInfo = new HashMap<String, CredentialInfo>();
-
-        public CredentialInfo createCredentialInfo(String name) {
-            CredentialInfo obj = new CredentialInfo(name);
-            credentialInfo.put(name, obj);
-            return obj;
-        }
-
-        public PerProviderSubscription() {
-        }
-
-        public PerProviderSubscription(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(UpdateIdentifier);
-            out.writeMap(credentialInfo);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                UpdateIdentifier = in.readString();
-                in.readMap(credentialInfo, CredentialInfo.class.getClassLoader());
-            }
-        }
-
-        public static final Parcelable.Creator<PerProviderSubscription> CREATOR = new Parcelable.Creator<PerProviderSubscription>() {
-            public PerProviderSubscription createFromParcel(Parcel in) {
-                return new PerProviderSubscription(in);
-            }
-
-            public PerProviderSubscription[] newArray(int size) {
-                return new PerProviderSubscription[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>
-     * This interior node contains the Home SP information, subscription policy, management and credential information.
-     **/
-    public static class CredentialInfo implements Parcelable {
-        public String nodeName;
-        public Policy policy = new Policy();
-        public String credentialPriority;
-        public HashMap<String, AAAServerTrustRoot> aAAServerTrustRoot = new HashMap<String, AAAServerTrustRoot>();
-        public SubscriptionUpdate subscriptionUpdate = new SubscriptionUpdate();
-        public HomeSP homeSP = new HomeSP();
-        public SubscriptionParameters subscriptionParameters = new SubscriptionParameters();
-        public Credential credential = new Credential();
-        public Extension extension = new Extension();
-
-        public CredentialInfo(String nn) {
-            nodeName = nn;
-        }
-
-        public AAAServerTrustRoot createAAAServerTrustRoot(String name, String url, String fp) {
-            AAAServerTrustRoot obj = new AAAServerTrustRoot(name, url, fp);
-            aAAServerTrustRoot.put(name, obj);
-            return obj;
-        }
-
-        public CredentialInfo() {
-        }
-
-        public CredentialInfo(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeParcelable(policy, flags);
-            out.writeString(credentialPriority);
-            out.writeMap(aAAServerTrustRoot);
-            out.writeParcelable(subscriptionUpdate, flags);
-            out.writeParcelable(homeSP, flags);
-            out.writeParcelable(subscriptionParameters, flags);
-            out.writeParcelable(credential, flags);
-            //out.writeParcelable(extension, flags);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                policy = in.readParcelable(Policy.class.getClassLoader());
-                credentialPriority = in.readString();
-                in.readMap(aAAServerTrustRoot, AAAServerTrustRoot.class.getClassLoader());
-                subscriptionUpdate = in.readParcelable(SubscriptionUpdate.class.getClassLoader());
-                homeSP = in.readParcelable(HomeSP.class.getClassLoader());
-                subscriptionParameters = in.readParcelable(SubscriptionParameters.class
-                        .getClassLoader());
-                credential = in.readParcelable(Credential.class.getClassLoader());
-                //extension = in.readParcelable(Extension.class.getClassLoader());
-            }
-        }
-
-        public static final Parcelable.Creator<CredentialInfo> CREATOR = new Parcelable.Creator<CredentialInfo>() {
-            public CredentialInfo createFromParcel(Parcel in) {
-                return new CredentialInfo(in);
-            }
-
-            public CredentialInfo[] newArray(int size) {
-                return new CredentialInfo[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Policy
-     **/
-    public static class Policy implements Parcelable {
-        public HashMap<String, PreferredRoamingPartnerList> preferredRoamingPartnerList = new HashMap<String, PreferredRoamingPartnerList>();
-        public HashMap<String, MinBackhaulThresholdNetwork> minBackhaulThreshold = new HashMap<String, MinBackhaulThresholdNetwork>();
-        public PolicyUpdate policyUpdate = new PolicyUpdate();
-        public HashMap<String, SPExclusionList> sPExclusionList = new HashMap<String, SPExclusionList>();
-        public HashMap<String, RequiredProtoPortTuple> requiredProtoPortTuple = new HashMap<String, RequiredProtoPortTuple>();
-        public String maximumBSSLoadValue;
-
-        public PreferredRoamingPartnerList createPreferredRoamingPartnerList(String name,
-                String fqdn, String priority, String country) {
-            PreferredRoamingPartnerList obj = new PreferredRoamingPartnerList(name, fqdn, priority,
-                    country);
-            preferredRoamingPartnerList.put(name, obj);
-            return obj;
-        }
-
-        public MinBackhaulThresholdNetwork createMinBackhaulThreshold(String name, String type,
-                String dl, String ul) {
-            MinBackhaulThresholdNetwork obj = new MinBackhaulThresholdNetwork(name, type, dl, ul);
-            minBackhaulThreshold.put(name, obj);
-            return obj;
-        }
-
-        public SPExclusionList createSPExclusionList(String name, String ssid) {
-            SPExclusionList obj = new SPExclusionList(name, ssid);
-            sPExclusionList.put(name, obj);
-            return obj;
-        }
-
-        public RequiredProtoPortTuple createRequiredProtoPortTuple(String name, String proto,
-                String port) {
-            RequiredProtoPortTuple obj = new RequiredProtoPortTuple(name, proto, port);
-            requiredProtoPortTuple.put(name, obj);
-            return obj;
-        }
-
-        public Policy() {
-        }
-
-        public Policy(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeMap(preferredRoamingPartnerList);
-            out.writeMap(minBackhaulThreshold);
-            out.writeParcelable(policyUpdate, flags);
-            out.writeMap(sPExclusionList);
-            out.writeMap(requiredProtoPortTuple);
-            out.writeString(maximumBSSLoadValue);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                in.readMap(preferredRoamingPartnerList,
-                        PreferredRoamingPartnerList.class.getClassLoader());
-                in.readMap(minBackhaulThreshold, MinBackhaulThresholdNetwork.class.getClassLoader());
-                policyUpdate = in.readParcelable(PolicyUpdate.class.getClassLoader());
-                in.readMap(sPExclusionList, SPExclusionList.class.getClassLoader());
-                in.readMap(requiredProtoPortTuple, RequiredProtoPortTuple.class.getClassLoader());
-                maximumBSSLoadValue = in.readString();
-
-            }
-        }
-
-        public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
-            public Policy createFromParcel(Parcel in) {
-                return new Policy(in);
-            }
-
-            public Policy[] newArray(int size) {
-                return new Policy[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Policy/PreferredRoamingPartnerList/<X+>
-     **/
-    public static class PreferredRoamingPartnerList implements Parcelable {
-        public String nodeName;
-        public String FQDN_Match; //maximum 255 + ",includeSubdomains", equals 273
-        public String Priority;
-        public String Country; // maximum 600 octets
-
-        public PreferredRoamingPartnerList(String nn, String f, String p, String c) {
-            nodeName = nn;
-            FQDN_Match = f;
-            Priority = p;
-            Country = c;
-        }
-
-        public PreferredRoamingPartnerList() {
-        }
-
-        public PreferredRoamingPartnerList(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeString(FQDN_Match);
-            out.writeString(Priority);
-            out.writeString(Country);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                FQDN_Match = in.readString();
-                Priority = in.readString();
-                Country = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<PreferredRoamingPartnerList> CREATOR = new Parcelable.Creator<PreferredRoamingPartnerList>() {
-            public PreferredRoamingPartnerList createFromParcel(Parcel in) {
-                return new PreferredRoamingPartnerList(in);
-            }
-
-            public PreferredRoamingPartnerList[] newArray(int size) {
-                return new PreferredRoamingPartnerList[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Policy/MinBackhaulThreshold
-     **/
-    public static class MinBackhaulThresholdNetwork implements Parcelable {
-        public String nodeName;
-        public String NetworkType;
-        public String DLBandwidth;
-        public String ULBandwidth;
-
-        public MinBackhaulThresholdNetwork(String nn, String nt, String d, String u) {
-            nodeName = nn;
-            NetworkType = nt;
-            DLBandwidth = d;
-            ULBandwidth = u;
-        }
-
-        public MinBackhaulThresholdNetwork() {
-        }
-
-        public MinBackhaulThresholdNetwork(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeString(NetworkType);
-            out.writeString(DLBandwidth);
-            out.writeString(ULBandwidth);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                NetworkType = in.readString();
-                DLBandwidth = in.readString();
-                ULBandwidth = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<MinBackhaulThresholdNetwork> CREATOR = new Parcelable.Creator<MinBackhaulThresholdNetwork>() {
-            public MinBackhaulThresholdNetwork createFromParcel(Parcel in) {
-                return new MinBackhaulThresholdNetwork(in);
-            }
-
-            public MinBackhaulThresholdNetwork[] newArray(int size) {
-                return new MinBackhaulThresholdNetwork[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Policy/PolicyUpdate
-     **/
-    public static class PolicyUpdate implements Parcelable {
-        public String UpdateInterval;
-        public String UpdateMethod;
-        public String Restriction;
-        public String URI;
-        public UsernamePassword usernamePassword = new UsernamePassword();
-        public String Other;
-        public TrustRoot trustRoot = new TrustRoot();
-
-        public PolicyUpdate() {
-        }
-
-        public PolicyUpdate(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(UpdateInterval);
-            out.writeString(UpdateMethod);
-            out.writeString(Restriction);
-            out.writeString(URI);
-            out.writeParcelable(usernamePassword, flags);
-            out.writeString(Other);
-            out.writeParcelable(trustRoot, flags);
-
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                UpdateInterval = in.readString();
-                UpdateMethod = in.readString();
-                Restriction = in.readString();
-                URI = in.readString();
-                usernamePassword = in.readParcelable(UsernamePassword.class.getClassLoader());
-                Other = in.readString();
-                trustRoot = in.readParcelable(TrustRoot.class.getClassLoader());
-            }
-        }
-
-        public static final Parcelable.Creator<PolicyUpdate> CREATOR = new Parcelable.Creator<PolicyUpdate>() {
-            public PolicyUpdate createFromParcel(Parcel in) {
-                return new PolicyUpdate(in);
-            }
-
-            public PolicyUpdate[] newArray(int size) {
-                return new PolicyUpdate[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Policy/SPExclusionList
-     **/
-    public static class SPExclusionList implements Parcelable {
-        public String nodeName;
-        public String SSID;
-
-        public SPExclusionList(String nn, String s) {
-            nodeName = nn;
-            SSID = s;
-        }
-
-        public SPExclusionList() {
-        }
-
-        public SPExclusionList(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeString(SSID);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                SSID = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<SPExclusionList> CREATOR = new Parcelable.Creator<SPExclusionList>() {
-            public SPExclusionList createFromParcel(Parcel in) {
-                return new SPExclusionList(in);
-            }
-
-            public SPExclusionList[] newArray(int size) {
-                return new SPExclusionList[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Policy/RequiredProtoPortTuple
-     **/
-    public static class RequiredProtoPortTuple implements Parcelable {
-        public String nodeName;
-        public String IPProtocol;
-        public String PortNumber;
-
-        public RequiredProtoPortTuple() {
-        }
-
-        public RequiredProtoPortTuple(String nn, String protocol, String port) {
-            nodeName = nn;
-            IPProtocol = protocol;
-            PortNumber = port;
-        }
-
-        public RequiredProtoPortTuple(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeString(IPProtocol);
-            out.writeString(PortNumber);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                IPProtocol = in.readString();
-                PortNumber = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<RequiredProtoPortTuple> CREATOR = new Parcelable.Creator<RequiredProtoPortTuple>() {
-            public RequiredProtoPortTuple createFromParcel(Parcel in) {
-                return new RequiredProtoPortTuple(in);
-            }
-
-            public RequiredProtoPortTuple[] newArray(int size) {
-                return new RequiredProtoPortTuple[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/AAAServerTrustRoot
-     **/
-    public static class AAAServerTrustRoot implements Parcelable {
-        public String nodeName;
-        public String CertURL;
-        public String CertSHA256Fingerprint;
-
-        public AAAServerTrustRoot(String nn, String url, String fp) {
-            nodeName = nn;
-            CertURL = url;
-            CertSHA256Fingerprint = fp;
-        }
-
-        public AAAServerTrustRoot() {
-        }
-
-        public AAAServerTrustRoot(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeString(CertURL);
-            out.writeString(CertSHA256Fingerprint);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                CertURL = in.readString();
-                CertSHA256Fingerprint = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<AAAServerTrustRoot> CREATOR = new Parcelable.Creator<AAAServerTrustRoot>() {
-            public AAAServerTrustRoot createFromParcel(Parcel in) {
-                return new AAAServerTrustRoot(in);
-            }
-
-            public AAAServerTrustRoot[] newArray(int size) {
-                return new AAAServerTrustRoot[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/SubscriptionUpdate
-     **/
-    public static class SubscriptionUpdate implements Parcelable {
-        public String UpdateInterval;
-        public String UpdateMethod;
-        public String Restriction;
-        public String URI;
-        public UsernamePassword usernamePassword = new UsernamePassword();
-        public String Other;
-        public TrustRoot trustRoot = new TrustRoot();
-
-        public SubscriptionUpdate() {
-        }
-
-        public SubscriptionUpdate(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(UpdateInterval);
-            out.writeString(UpdateMethod);
-            out.writeString(Restriction);
-            out.writeString(URI);
-            out.writeParcelable(usernamePassword, flags);
-            out.writeString(Other);
-            out.writeParcelable(trustRoot, flags);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                UpdateInterval = in.readString();
-                UpdateMethod = in.readString();
-                Restriction = in.readString();
-                URI = in.readString();
-                usernamePassword = in.readParcelable(UsernamePassword.class.getClassLoader());
-                Other = in.readString();
-                trustRoot = in.readParcelable(TrustRoot.class.getClassLoader());
-            }
-        }
-
-        public static final Parcelable.Creator<SubscriptionUpdate> CREATOR = new Parcelable.Creator<SubscriptionUpdate>() {
-            public SubscriptionUpdate createFromParcel(Parcel in) {
-                return new SubscriptionUpdate(in);
-            }
-
-            public SubscriptionUpdate[] newArray(int size) {
-                return new SubscriptionUpdate[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Policy/PolicyUpdate/TrustRoot
-     * PerProviderSubscription/<X+>/SubscriptionUpdate/TrustRoot
-     * PerProviderSubscription/<X+>/AAAServerTrustRoot/<X+>
-     **/
-    public static class TrustRoot implements Parcelable {
-        public String CertURL;
-        public String CertSHA256Fingerprint;
-
-        public TrustRoot() {
-        }
-
-        public TrustRoot(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(CertURL);
-            out.writeString(CertSHA256Fingerprint);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                CertURL = in.readString();
-                CertSHA256Fingerprint = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<TrustRoot> CREATOR = new Parcelable.Creator<TrustRoot>() {
-            public TrustRoot createFromParcel(Parcel in) {
-                return new TrustRoot(in);
-            }
-
-            public TrustRoot[] newArray(int size) {
-                return new TrustRoot[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Policy/PolicyUpdate/UsernamePassword
-     * PerProviderSubscription/<X+>/SubscriptionUpdate/UsernamePassword
-     * PerProviderSubscription/<X+>/Credential/UsernamePassword
-     **/
-    public static class UsernamePassword implements Parcelable {
-        public String Username;
-        public String Password;
-        //following are Credential node used only
-        public boolean MachineManaged;
-        public String SoftTokenApp;
-        public String AbleToShare;
-        public EAPMethod eAPMethod = new EAPMethod();
-
-        public UsernamePassword() {
-        }
-
-        public UsernamePassword(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(Username);
-            out.writeString(Password);
-            out.writeInt(MachineManaged ? 1 : 0);
-            out.writeString(SoftTokenApp);
-            out.writeString(AbleToShare);
-            out.writeParcelable(eAPMethod, flags);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                Username = in.readString();
-                Password = in.readString();
-                MachineManaged = (in.readInt() == 1) ? true : false;
-                SoftTokenApp = in.readString();
-                AbleToShare = in.readString();
-                eAPMethod = in.readParcelable(EAPMethod.class.getClassLoader());
-            }
-        }
-
-        public static final Parcelable.Creator<UsernamePassword> CREATOR = new Parcelable.Creator<UsernamePassword>() {
-            public UsernamePassword createFromParcel(Parcel in) {
-                return new UsernamePassword(in);
-            }
-
-            public UsernamePassword[] newArray(int size) {
-                return new UsernamePassword[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Credential/UsernamePassword/EAPMethod
-     **/
-    public static class EAPMethod implements Parcelable {
-        public String EAPType;
-        public String VendorId;
-        public String VendorType;
-        public String InnerEAPType;
-        public String InnerVendorId;
-        public String InnerVendorType;
-        public String InnerMethod;
-
-        public EAPMethod() {
-        }
-
-        public EAPMethod(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(EAPType);
-            out.writeString(VendorId);
-            out.writeString(VendorType);
-            out.writeString(InnerEAPType);
-            out.writeString(InnerVendorId);
-            out.writeString(InnerVendorType);
-            out.writeString(InnerMethod);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                EAPType = in.readString();
-                VendorId = in.readString();
-                VendorType = in.readString();
-                InnerEAPType = in.readString();
-                InnerVendorId = in.readString();
-                InnerVendorType = in.readString();
-                InnerMethod = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<EAPMethod> CREATOR = new Parcelable.Creator<EAPMethod>() {
-            public EAPMethod createFromParcel(Parcel in) {
-                return new EAPMethod(in);
-            }
-
-            public EAPMethod[] newArray(int size) {
-                return new EAPMethod[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/HomeSP
-     **/
-    public static class HomeSP implements Parcelable {
-        public HashMap<String, NetworkID> networkID = new HashMap<String, NetworkID>();
-        public String FriendlyName;
-        public String IconURL;
-        public String FQDN;
-        public HashMap<String, HomeOIList> homeOIList = new HashMap<String, HomeOIList>();
-        public HashMap<String, OtherHomePartners> otherHomePartners = new HashMap<String, OtherHomePartners>();
-        public String RoamingConsortiumOI;
-
-        public NetworkID createNetworkID(String name, String ssid, String hessid) {
-            NetworkID obj = new NetworkID(name, ssid, hessid);
-            networkID.put(name, obj);
-            return obj;
-        }
-
-        public HomeOIList createHomeOIList(String name, String homeoi, boolean required) {
-            HomeOIList obj = new HomeOIList(name, homeoi, required);
-            homeOIList.put(name, obj);
-            return obj;
-        }
-
-        public OtherHomePartners createOtherHomePartners(String name, String fqdn) {
-            OtherHomePartners obj = new OtherHomePartners(name, fqdn);
-            otherHomePartners.put(name, obj);
-            return obj;
-        }
-
-        public HomeSP() {
-        }
-
-        public HomeSP(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeMap(networkID);
-            out.writeString(FriendlyName);
-            out.writeString(IconURL);
-            out.writeString(FQDN);
-            out.writeMap(homeOIList);
-            out.writeMap(otherHomePartners);
-            out.writeString(RoamingConsortiumOI);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                in.readMap(networkID, NetworkID.class.getClassLoader());
-                FriendlyName = in.readString();
-                IconURL = in.readString();
-                FQDN = in.readString();
-                in.readMap(homeOIList, HomeOIList.class.getClassLoader());
-                in.readMap(otherHomePartners, OtherHomePartners.class.getClassLoader());
-                RoamingConsortiumOI = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<HomeSP> CREATOR = new Parcelable.Creator<HomeSP>() {
-            public HomeSP createFromParcel(Parcel in) {
-                return new HomeSP(in);
-            }
-
-            public HomeSP[] newArray(int size) {
-                return new HomeSP[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/HomeSP/NetworkID
-     **/
-    public static class NetworkID implements Parcelable {
-        public String nodeName;
-        public String SSID;
-        public String HESSID;
-
-        public NetworkID(String nn, String s, String h) {
-            nodeName = nn;
-            SSID = s;
-            HESSID = h;
-        }
-
-        public NetworkID() {
-        }
-
-        public NetworkID(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeString(SSID);
-            out.writeString(HESSID);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                SSID = in.readString();
-                HESSID = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<NetworkID> CREATOR = new Parcelable.Creator<NetworkID>() {
-            public NetworkID createFromParcel(Parcel in) {
-                return new NetworkID(in);
-            }
-
-            public NetworkID[] newArray(int size) {
-                return new NetworkID[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/HomeSP/HomeOIList
-     **/
-    public static class HomeOIList implements Parcelable {
-        public String nodeName;
-        public String HomeOI;
-        public boolean HomeOIRequired;
-
-        public HomeOIList(String nn, String h, boolean r) {
-            nodeName = nn;
-            HomeOI = h;
-            HomeOIRequired = r;
-        }
-
-        public HomeOIList() {
-        }
-
-        public HomeOIList(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeString(HomeOI);
-            out.writeInt(HomeOIRequired ? 1 : 0);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                HomeOI = in.readString();
-                HomeOIRequired = (in.readInt() == 1) ? true : false;
-            }
-        }
-
-        public static final Parcelable.Creator<HomeOIList> CREATOR = new Parcelable.Creator<HomeOIList>() {
-            public HomeOIList createFromParcel(Parcel in) {
-                return new HomeOIList(in);
-            }
-
-            public HomeOIList[] newArray(int size) {
-                return new HomeOIList[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/HomeSP/OtherHomePartners
-     **/
-    public static class OtherHomePartners implements Parcelable {
-        public String nodeName;
-        public String FQDN;
-
-        public OtherHomePartners(String nn, String f) {
-            nodeName = nn;
-            FQDN = f;
-        }
-
-        public OtherHomePartners() {
-        }
-
-        public OtherHomePartners(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(nodeName);
-            out.writeString(FQDN);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                nodeName = in.readString();
-                FQDN = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<OtherHomePartners> CREATOR = new Parcelable.Creator<OtherHomePartners>() {
-            public OtherHomePartners createFromParcel(Parcel in) {
-                return new OtherHomePartners(in);
-            }
-
-            public OtherHomePartners[] newArray(int size) {
-                return new OtherHomePartners[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/SubscriptionParameters
-     **/
-    public static class SubscriptionParameters implements Parcelable {
-        public String CreationDate;
-        public String ExpirationDate;
-        public String TypeOfSubscription;
-        public UsageLimits usageLimits = new UsageLimits();
-
-        public SubscriptionParameters() {
-        }
-
-        public SubscriptionParameters(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(CreationDate);
-            out.writeString(ExpirationDate);
-            out.writeString(TypeOfSubscription);
-            out.writeParcelable(usageLimits, flags);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                CreationDate = in.readString();
-                ExpirationDate = in.readString();
-                TypeOfSubscription = in.readString();
-                usageLimits = in.readParcelable(UsageLimits.class.getClassLoader());
-            }
-        }
-
-        public static final Parcelable.Creator<SubscriptionParameters> CREATOR = new Parcelable.Creator<SubscriptionParameters>() {
-            public SubscriptionParameters createFromParcel(Parcel in) {
-                return new SubscriptionParameters(in);
-            }
-
-            public SubscriptionParameters[] newArray(int size) {
-                return new SubscriptionParameters[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/SubscriptionParameters/UsageLimits
-     **/
-    public static class UsageLimits implements Parcelable {
-        public String DataLimit;
-        public String StartDate;
-        public String TimeLimit;
-        public String UsageTimePeriod;
-
-        public UsageLimits() {
-        }
-
-        public UsageLimits(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(DataLimit);
-            out.writeString(StartDate);
-            out.writeString(TimeLimit);
-            out.writeString(UsageTimePeriod);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                DataLimit = in.readString();
-                StartDate = in.readString();
-                TimeLimit = in.readString();
-                UsageTimePeriod = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<UsageLimits> CREATOR = new Parcelable.Creator<UsageLimits>() {
-            public UsageLimits createFromParcel(Parcel in) {
-                return new UsageLimits(in);
-            }
-
-            public UsageLimits[] newArray(int size) {
-                return new UsageLimits[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Credential
-     **/
-    public static class Credential implements Parcelable {
-        public String CreationDate;
-        public String ExpirationDate;
-        public UsernamePassword usernamePassword = new UsernamePassword();
-        public DigitalCertificate digitalCertificate = new DigitalCertificate();
-        public String Realm;
-        public boolean CheckAAAServerCertStatus;
-        public SIM sim = new SIM();
-
-        public Credential() {
-        }
-
-        public Credential(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(CreationDate);
-            out.writeString(ExpirationDate);
-            out.writeParcelable(usernamePassword, flags);
-            out.writeParcelable(digitalCertificate, flags);
-            out.writeString(Realm);
-            out.writeInt(CheckAAAServerCertStatus ? 1 : 0);
-            out.writeParcelable(sim, flags);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                CreationDate = in.readString();
-                ExpirationDate = in.readString();
-                usernamePassword = in.readParcelable(UsernamePassword.class.getClassLoader());
-                digitalCertificate = in.readParcelable(DigitalCertificate.class.getClassLoader());
-                Realm = in.readString();
-                CheckAAAServerCertStatus = (in.readInt() == 1) ? true : false;
-                sim = in.readParcelable(SIM.class.getClassLoader());
-            }
-        }
-
-        public static final Parcelable.Creator<Credential> CREATOR = new Parcelable.Creator<Credential>() {
-            public Credential createFromParcel(Parcel in) {
-                return new Credential(in);
-            }
-
-            public Credential[] newArray(int size) {
-                return new Credential[size];
-            }
-        };
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Credential/DigitalCertificate
-     **/
-    public static class DigitalCertificate implements Parcelable {
-        public String CertificateType;
-        public String CertSHA256Fingerprint;
-
-        public DigitalCertificate() {
-        }
-
-        public DigitalCertificate(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(CertificateType);
-            out.writeString(CertSHA256Fingerprint);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                CertificateType = in.readString();
-                CertSHA256Fingerprint = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<DigitalCertificate> CREATOR = new Parcelable.Creator<DigitalCertificate>() {
-            public DigitalCertificate createFromParcel(Parcel in) {
-                return new DigitalCertificate(in);
-            }
-
-            public DigitalCertificate[] newArray(int size) {
-                return new DigitalCertificate[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Credential/SIM
-     **/
-    public static class SIM implements Parcelable {
-        public String IMSI;
-        public String EAPType;
-
-        public SIM() {
-        }
-
-        public SIM(Parcel in) {
-            readFromParcel(in);
-        }
-
-        public int describeContents() {
-            return 0;
-        }
-
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(IMSI);
-            out.writeString(EAPType);
-        }
-
-        public void readFromParcel(Parcel in) {
-            if (in == null) {
-                //log here
-            } else {
-                IMSI = in.readString();
-                EAPType = in.readString();
-            }
-        }
-
-        public static final Parcelable.Creator<SIM> CREATOR = new Parcelable.Creator<SIM>() {
-            public SIM createFromParcel(Parcel in) {
-                return new SIM(in);
-            }
-
-            public SIM[] newArray(int size) {
-                return new SIM[size];
-            }
-        };
-
-    }
-
-    /**
-     * PerProviderSubscription/<X+>/Extension
-     **/
-    public static class Extension {
-        public String empty;
-    }
-
-    public WifiPasspointDmTree() {
-    }
-
-    public WifiPasspointDmTree(Parcel in) {
-        readFromParcel(in);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeMap(spFqdn);
-    }
-
-    public void readFromParcel(Parcel in) {
-        if (in == null) {
-            //log here
-        } else {
-            in.readMap(spFqdn, SpFqdn.class.getClassLoader());
-        }
-    }
-
-    public static final Parcelable.Creator<WifiPasspointDmTree> CREATOR = new Parcelable.Creator<WifiPasspointDmTree>() {
-        public WifiPasspointDmTree createFromParcel(Parcel in) {
-            return new WifiPasspointDmTree(in);
-        }
-
-        public WifiPasspointDmTree[] newArray(int size) {
-            return new WifiPasspointDmTree[size];
-        }
-    };
-
-}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java
deleted file mode 100644
index 33db3f5..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** @hide */
-public class WifiPasspointInfo implements Parcelable {
-
-    /** TODO doc */
-    public static final int ANQP_CAPABILITY = 1 << 0;
-
-    /** TODO doc */
-    public static final int VENUE_NAME = 1 << 1;
-
-    /** TODO doc */
-    public static final int NETWORK_AUTH_TYPE = 1 << 2;
-
-    /** TODO doc */
-    public static final int ROAMING_CONSORTIUM = 1 << 3;
-
-    /** TODO doc */
-    public static final int IP_ADDR_TYPE_AVAILABILITY = 1 << 4;
-
-    /** TODO doc */
-    public static final int NAI_REALM = 1 << 5;
-
-    /** TODO doc */
-    public static final int CELLULAR_NETWORK = 1 << 6;
-
-    /** TODO doc */
-    public static final int DOMAIN_NAME = 1 << 7;
-
-    /** TODO doc */
-    public static final int HOTSPOT_CAPABILITY = 1 << 8;
-
-    /** TODO doc */
-    public static final int OPERATOR_FRIENDLY_NAME = 1 << 9;
-
-    /** TODO doc */
-    public static final int WAN_METRICS = 1 << 10;
-
-    /** TODO doc */
-    public static final int CONNECTION_CAPABILITY = 1 << 11;
-
-    /** TODO doc */
-    public static final int OSU_PROVIDER = 1 << 12;
-
-    /** TODO doc */
-    public static final int PRESET_CRED_MATCH =
-            ANQP_CAPABILITY |
-                    HOTSPOT_CAPABILITY |
-                    NAI_REALM |
-                    CELLULAR_NETWORK |
-                    DOMAIN_NAME;
-
-    /** TODO doc */
-    public static final int PRESET_ALL =
-            ANQP_CAPABILITY |
-                    VENUE_NAME |
-                    NETWORK_AUTH_TYPE |
-                    ROAMING_CONSORTIUM |
-                    IP_ADDR_TYPE_AVAILABILITY |
-                    NAI_REALM |
-                    CELLULAR_NETWORK |
-                    DOMAIN_NAME |
-                    HOTSPOT_CAPABILITY |
-                    OPERATOR_FRIENDLY_NAME |
-                    WAN_METRICS |
-                    CONNECTION_CAPABILITY |
-                    OSU_PROVIDER;
-
-
-    public static class WanMetrics {
-        public static final int STATUS_RESERVED = 0;
-        public static final int STATUS_UP = 1;
-        public static final int STATUS_DOWN = 2;
-        public static final int STATUS_TEST = 3;
-
-        public int wanInfo;
-        public long downlinkSpeed;
-        public long uplinkSpeed;
-        public int downlinkLoad;
-        public int uplinkLoad;
-        public int lmd;
-
-        public int getLinkStatus() {
-            return wanInfo & 0x3;
-        }
-
-        public boolean getSymmetricLink() {
-            return (wanInfo & (1 << 2)) != 0;
-        }
-
-        public boolean getAtCapacity() {
-            return (wanInfo & (1 << 3)) != 0;
-        }
-
-        @Override
-        public String toString() {
-            return wanInfo + "," + downlinkSpeed + "," + uplinkSpeed + "," +
-                    downlinkLoad + "," + uplinkLoad + "," + lmd;
-        }
-    }
-
-    public static class IpProtoPort {
-        public static final int STATUS_CLOSED = 0;
-        public static final int STATUS_OPEN = 1;
-        public static final int STATUS_UNKNOWN = 2;
-
-        public int proto;
-        public int port;
-        public int status;
-
-        @Override
-        public String toString() {
-            return proto + "," + port + "," + status;
-        }
-    }
-
-    public static class NetworkAuthType {
-        public static final int TYPE_TERMS_AND_CONDITION = 0;
-        public static final int TYPE_ONLINE_ENROLLMENT = 1;
-        public static final int TYPE_HTTP_REDIRECTION = 2;
-        public static final int TYPE_DNS_REDIRECTION = 3;
-
-        public int type;
-        public String redirectUrl;
-
-        @Override
-        public String toString() {
-            return type + "," + redirectUrl;
-        }
-    }
-
-    public static class IpAddressType {
-        public static final int IPV6_NOT_AVAILABLE = 0;
-        public static final int IPV6_AVAILABLE = 1;
-        public static final int IPV6_UNKNOWN = 2;
-
-        public static final int IPV4_NOT_AVAILABLE = 0;
-        public static final int IPV4_PUBLIC = 1;
-        public static final int IPV4_PORT_RESTRICTED = 2;
-        public static final int IPV4_SINGLE_NAT = 3;
-        public static final int IPV4_DOUBLE_NAT = 4;
-        public static final int IPV4_PORT_RESTRICTED_SINGLE_NAT = 5;
-        public static final int IPV4_PORT_RESTRICTED_DOUBLE_NAT = 6;
-        public static final int IPV4_PORT_UNKNOWN = 7;
-
-        private static final int NULL_VALUE = -1;
-
-        public int availability;
-
-        public int getIpv6Availability() {
-            return availability & 0x3;
-        }
-
-        public int getIpv4Availability() {
-            return (availability & 0xFF) >> 2;
-        }
-
-        @Override
-        public String toString() {
-            return getIpv6Availability() + "," + getIpv4Availability();
-        }
-    }
-
-    public static class NaiRealm {
-        public static final int ENCODING_RFC4282 = 0;
-        public static final int ENCODING_UTF8 = 1;
-
-        public int encoding;
-        public String realm;
-
-        @Override
-        public String toString() {
-            return encoding + "," + realm;
-        }
-    }
-
-    public static class CellularNetwork {
-        public String mcc;
-        public String mnc;
-
-        @Override
-        public String toString() {
-            return mcc + "," + mnc;
-        }
-    }
-
-    /** BSSID */
-    public String bssid;
-
-    /** venue name */
-    public String venueName;
-
-    /** list of network authentication types */
-    public List<NetworkAuthType> networkAuthTypeList;
-
-    /** list of roaming consortium OIs */
-    public List<String> roamingConsortiumList;
-
-    /** IP address availability */
-    public IpAddressType ipAddrTypeAvailability;
-
-    /** list of NAI realm */
-    public List<NaiRealm> naiRealmList;
-
-    /** list of 3GPP cellular network */
-    public List<CellularNetwork> cellularNetworkList;
-
-    /** list of fully qualified domain name (FQDN) */
-    public List<String> domainNameList;
-
-    /** HS 2.0 operator friendly name */
-    public String operatorFriendlyName;
-
-    /** HS 2.0 wan metrics */
-    public WanMetrics wanMetrics;
-
-    /** list of HS 2.0 IP proto port */
-    public List<IpProtoPort> connectionCapabilityList;
-
-    /** list of HS 2.0 OSU providers */
-    public List<WifiPasspointOsuProvider> osuProviderList;
-
-    /**
-     * Convert mask to ANQP subtypes, for supplicant command use.
-     *
-     * @param mask The ANQP subtypes mask.
-     * @return String of ANQP subtypes, good for supplicant command use
-     * @hide
-     */
-    public static String toAnqpSubtypes(int mask) {
-        StringBuilder sb = new StringBuilder();
-        if ((mask & ANQP_CAPABILITY) != 0)
-            sb.append("257,");
-        if ((mask & VENUE_NAME) != 0)
-            sb.append("258,");
-        if ((mask & NETWORK_AUTH_TYPE) != 0)
-            sb.append("260,");
-        if ((mask & ROAMING_CONSORTIUM) != 0)
-            sb.append("261,");
-        if ((mask & IP_ADDR_TYPE_AVAILABILITY) != 0)
-            sb.append("262,");
-        if ((mask & NAI_REALM) != 0)
-            sb.append("263,");
-        if ((mask & CELLULAR_NETWORK) != 0)
-            sb.append("264,");
-        if ((mask & DOMAIN_NAME) != 0)
-            sb.append("268,");
-        if ((mask & HOTSPOT_CAPABILITY) != 0)
-            sb.append("hs20:2,");
-        if ((mask & OPERATOR_FRIENDLY_NAME) != 0)
-            sb.append("hs20:3,");
-        if ((mask & WAN_METRICS) != 0)
-            sb.append("hs20:4,");
-        if ((mask & CONNECTION_CAPABILITY) != 0)
-            sb.append("hs20:5,");
-        if ((mask & OSU_PROVIDER) != 0)
-            sb.append("hs20:8,");
-        if (sb.length() > 0)
-            sb.deleteCharAt(sb.length() - 1);
-        return sb.toString();
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-
-        sb.append("BSSID: ").append("(").append(bssid).append(")");
-
-        if (venueName != null)
-            sb.append(" venueName: ").append("(")
-              .append(venueName.replace("\n", "\\n")).append(")");
-
-        if (networkAuthTypeList != null) {
-            sb.append(" networkAuthType: ");
-            for (NetworkAuthType auth : networkAuthTypeList)
-                sb.append("(").append(auth.toString()).append(")");
-        }
-
-        if (roamingConsortiumList != null) {
-            sb.append(" roamingConsortium: ");
-            for (String oi : roamingConsortiumList)
-                sb.append("(").append(oi).append(")");
-        }
-
-        if (ipAddrTypeAvailability != null) {
-            sb.append(" ipAddrTypeAvaibility: ").append("(")
-              .append(ipAddrTypeAvailability.toString()).append(")");
-        }
-
-        if (naiRealmList != null) {
-            sb.append(" naiRealm: ");
-            for (NaiRealm realm : naiRealmList)
-                sb.append("(").append(realm.toString()).append(")");
-        }
-
-        if (cellularNetworkList != null) {
-            sb.append(" cellularNetwork: ");
-            for (CellularNetwork plmn : cellularNetworkList)
-                sb.append("(").append(plmn.toString()).append(")");
-        }
-
-        if (domainNameList != null) {
-            sb.append(" domainName: ");
-            for (String fqdn : domainNameList)
-                sb.append("(").append(fqdn).append(")");
-        }
-
-        if (operatorFriendlyName != null)
-            sb.append(" operatorFriendlyName: ").append("(")
-              .append(operatorFriendlyName).append(")");
-
-        if (wanMetrics != null)
-            sb.append(" wanMetrics: ").append("(")
-              .append(wanMetrics.toString()).append(")");
-
-        if (connectionCapabilityList != null) {
-            sb.append(" connectionCapability: ");
-            for (IpProtoPort ip : connectionCapabilityList)
-                sb.append("(").append(ip.toString()).append(")");
-        }
-
-        if (osuProviderList != null) {
-            sb.append(" osuProviderList: ");
-            for (WifiPasspointOsuProvider osu : osuProviderList)
-                sb.append("(").append(osu.toString()).append(")");
-        }
-
-        return sb.toString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(bssid);
-        out.writeString(venueName);
-
-        if (networkAuthTypeList == null) {
-            out.writeInt(0);
-        } else {
-            out.writeInt(networkAuthTypeList.size());
-            for (NetworkAuthType auth : networkAuthTypeList) {
-                out.writeInt(auth.type);
-                out.writeString(auth.redirectUrl);
-            }
-        }
-
-        if (roamingConsortiumList == null) {
-            out.writeInt(0);
-        } else {
-            out.writeInt(roamingConsortiumList.size());
-            for (String oi : roamingConsortiumList)
-                out.writeString(oi);
-        }
-
-        if (ipAddrTypeAvailability == null) {
-            out.writeInt(IpAddressType.NULL_VALUE);
-        } else {
-            out.writeInt(ipAddrTypeAvailability.availability);
-        }
-
-        if (naiRealmList == null) {
-            out.writeInt(0);
-        } else {
-            out.writeInt(naiRealmList.size());
-            for (NaiRealm realm : naiRealmList) {
-                out.writeInt(realm.encoding);
-                out.writeString(realm.realm);
-            }
-        }
-
-        if (cellularNetworkList == null) {
-            out.writeInt(0);
-        } else {
-            out.writeInt(cellularNetworkList.size());
-            for (CellularNetwork plmn : cellularNetworkList) {
-                out.writeString(plmn.mcc);
-                out.writeString(plmn.mnc);
-            }
-        }
-
-
-        if (domainNameList == null) {
-            out.writeInt(0);
-        } else {
-            out.writeInt(domainNameList.size());
-            for (String fqdn : domainNameList)
-                out.writeString(fqdn);
-        }
-
-        out.writeString(operatorFriendlyName);
-
-        if (wanMetrics == null) {
-            out.writeInt(0);
-        } else {
-            out.writeInt(1);
-            out.writeInt(wanMetrics.wanInfo);
-            out.writeLong(wanMetrics.downlinkSpeed);
-            out.writeLong(wanMetrics.uplinkSpeed);
-            out.writeInt(wanMetrics.downlinkLoad);
-            out.writeInt(wanMetrics.uplinkLoad);
-            out.writeInt(wanMetrics.lmd);
-        }
-
-        if (connectionCapabilityList == null) {
-            out.writeInt(0);
-        } else {
-            out.writeInt(connectionCapabilityList.size());
-            for (IpProtoPort ip : connectionCapabilityList) {
-                out.writeInt(ip.proto);
-                out.writeInt(ip.port);
-                out.writeInt(ip.status);
-            }
-        }
-
-        if (osuProviderList == null) {
-            out.writeInt(0);
-        } else {
-            out.writeInt(osuProviderList.size());
-            for (WifiPasspointOsuProvider osu : osuProviderList)
-                osu.writeToParcel(out, flags);
-        }
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public static final Parcelable.Creator<WifiPasspointInfo> CREATOR =
-            new Parcelable.Creator<WifiPasspointInfo>() {
-                @Override
-                public WifiPasspointInfo createFromParcel(Parcel in) {
-                    WifiPasspointInfo p = new WifiPasspointInfo();
-                    int n;
-
-                    p.bssid = in.readString();
-                    p.venueName = in.readString();
-
-                    n = in.readInt();
-                    if (n > 0) {
-                        p.networkAuthTypeList = new ArrayList<NetworkAuthType>();
-                        for (int i = 0; i < n; i++) {
-                            NetworkAuthType auth = new NetworkAuthType();
-                            auth.type = in.readInt();
-                            auth.redirectUrl = in.readString();
-                            p.networkAuthTypeList.add(auth);
-                        }
-                    }
-
-                    n = in.readInt();
-                    if (n > 0) {
-                        p.roamingConsortiumList = new ArrayList<String>();
-                        for (int i = 0; i < n; i++)
-                            p.roamingConsortiumList.add(in.readString());
-                    }
-
-                    n = in.readInt();
-                    if (n != IpAddressType.NULL_VALUE) {
-                        p.ipAddrTypeAvailability = new IpAddressType();
-                        p.ipAddrTypeAvailability.availability = n;
-                    }
-
-                    n = in.readInt();
-                    if (n > 0) {
-                        p.naiRealmList = new ArrayList<NaiRealm>();
-                        for (int i = 0; i < n; i++) {
-                            NaiRealm realm = new NaiRealm();
-                            realm.encoding = in.readInt();
-                            realm.realm = in.readString();
-                            p.naiRealmList.add(realm);
-                        }
-                    }
-
-                    n = in.readInt();
-                    if (n > 0) {
-                        p.cellularNetworkList = new ArrayList<CellularNetwork>();
-                        for (int i = 0; i < n; i++) {
-                            CellularNetwork plmn = new CellularNetwork();
-                            plmn.mcc = in.readString();
-                            plmn.mnc = in.readString();
-                            p.cellularNetworkList.add(plmn);
-                        }
-                    }
-
-                    n = in.readInt();
-                    if (n > 0) {
-                        p.domainNameList = new ArrayList<String>();
-                        for (int i = 0; i < n; i++)
-                            p.domainNameList.add(in.readString());
-                    }
-
-                    p.operatorFriendlyName = in.readString();
-
-                    n = in.readInt();
-                    if (n > 0) {
-                        p.wanMetrics = new WanMetrics();
-                        p.wanMetrics.wanInfo = in.readInt();
-                        p.wanMetrics.downlinkSpeed = in.readLong();
-                        p.wanMetrics.uplinkSpeed = in.readLong();
-                        p.wanMetrics.downlinkLoad = in.readInt();
-                        p.wanMetrics.uplinkLoad = in.readInt();
-                        p.wanMetrics.lmd = in.readInt();
-                    }
-
-                    n = in.readInt();
-                    if (n > 0) {
-                        p.connectionCapabilityList = new ArrayList<IpProtoPort>();
-                        for (int i = 0; i < n; i++) {
-                            IpProtoPort ip = new IpProtoPort();
-                            ip.proto = in.readInt();
-                            ip.port = in.readInt();
-                            ip.status = in.readInt();
-                            p.connectionCapabilityList.add(ip);
-                        }
-                    }
-
-                    n = in.readInt();
-                    if (n > 0) {
-                        p.osuProviderList = new ArrayList<WifiPasspointOsuProvider>();
-                        for (int i = 0; i < n; i++) {
-                            WifiPasspointOsuProvider osu = WifiPasspointOsuProvider.CREATOR
-                                    .createFromParcel(in);
-                            p.osuProviderList.add(osu);
-                        }
-                    }
-
-                    return p;
-                }
-
-                @Override
-                public WifiPasspointInfo[] newArray(int size) {
-                    return new WifiPasspointInfo[size];
-                }
-            };
-}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java
deleted file mode 100644
index 0245a3d..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-import android.content.Context;
-import android.net.wifi.ScanResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Provides APIs for managing Wifi Passpoint credentials.
- * @hide
- */
-public class WifiPasspointManager {
-
-    private static final String TAG = "PasspointManager";
-
-    private static final boolean DBG = true;
-
-    /* Passpoint states values */
-
-    /** Passpoint is in an unknown state. This should only occur in boot time */
-    public static final int PASSPOINT_STATE_UNKNOWN = 0;
-
-    /** Passpoint is disabled. This occurs when wifi is disabled */
-    public static final int PASSPOINT_STATE_DISABLED = 1;
-
-    /** Passpoint is enabled and in discovery state */
-    public static final int PASSPOINT_STATE_DISCOVERY = 2;
-
-    /** Passpoint is enabled and in access state */
-    public static final int PASSPOINT_STATE_ACCESS = 3;
-
-    /** Passpoint is enabled and in provisioning state */
-    public static final int PASSPOINT_STATE_PROVISION = 4;
-
-    /* Passpoint callback error codes */
-
-    /** Indicates that the operation failed due to an internal error */
-    public static final int REASON_ERROR = 0;
-
-    /** Indicates that the operation failed because wifi is disabled */
-    public static final int REASON_WIFI_DISABLED = 1;
-
-    /** Indicates that the operation failed because the framework is busy */
-    public static final int REASON_BUSY = 2;
-
-    /** Indicates that the operation failed because parameter is invalid */
-    public static final int REASON_INVALID_PARAMETER = 3;
-
-    /** Indicates that the operation failed because the server is not trusted */
-    public static final int REASON_NOT_TRUSTED = 4;
-
-    /**
-     * protocol supported for Passpoint
-     */
-    public static final String PROTOCOL_DM = "OMA-DM-ClientInitiated";
-
-    /**
-     * protocol supported for Passpoint
-     */
-    public static final String PROTOCOL_SOAP = "SPP-ClientInitiated";
-
-    /* Passpoint broadcasts */
-
-    /**
-     * Broadcast intent action indicating that the state of Passpoint
-     * connectivity has changed
-     */
-    public static final String PASSPOINT_STATE_CHANGED_ACTION =
-            "android.net.wifi.passpoint.STATE_CHANGE";
-
-    /**
-     * Broadcast intent action indicating that the saved Passpoint credential
-     * list has changed
-     */
-    public static final String PASSPOINT_CRED_CHANGED_ACTION =
-            "android.net.wifi.passpoint.CRED_CHANGE";
-
-    /**
-     * Broadcast intent action indicating that Passpoint online sign up is
-     * avaiable.
-     */
-    public static final String PASSPOINT_OSU_AVAILABLE_ACTION =
-            "android.net.wifi.passpoint.OSU_AVAILABLE";
-
-    /**
-     * Broadcast intent action indicating that user remediation is required
-     */
-    public static final String PASSPOINT_USER_REM_REQ_ACTION =
-            "android.net.wifi.passpoint.USER_REM_REQ";
-
-    /**
-     * Interface for callback invocation when framework channel is lost
-     */
-    public interface ChannelListener {
-        /**
-         * The channel to the framework has been disconnected. Application could
-         * try re-initializing using {@link #initialize}
-         */
-        public void onChannelDisconnected();
-    }
-
-    /**
-     * Interface for callback invocation on an application action
-     */
-    public interface ActionListener {
-        /** The operation succeeded */
-        public void onSuccess();
-
-        /**
-         * The operation failed
-         *
-         * @param reason The reason for failure could be one of
-         *            {@link #WIFI_DISABLED}, {@link #ERROR} or {@link #BUSY}
-         */
-        public void onFailure(int reason);
-    }
-
-    /**
-     * Interface for callback invocation when doing OSU or user remediation
-     */
-    public interface OsuRemListener {
-        /** The operation succeeded */
-        public void onSuccess();
-
-        /**
-         * The operation failed
-         *
-         * @param reason The reason for failure could be one of
-         *            {@link #WIFI_DISABLED}, {@link #ERROR} or {@link #BUSY}
-         */
-        public void onFailure(int reason);
-
-        /**
-         * Browser launch is requried for user interaction. When this callback
-         * is called, app should launch browser / webview to the given URI.
-         *
-         * @param uri URI for browser launch
-         */
-        public void onBrowserLaunch(String uri);
-
-        /**
-         * When this is called, app should dismiss the previously lanched browser.
-         */
-        public void onBrowserDismiss();
-    }
-
-    /**
-     * A channel that connects the application to the wifi passpoint framework.
-     * Most passpoint operations require a Channel as an argument.
-     * An instance of Channel is obtained by doing a call on {@link #initialize}
-     */
-    public static class Channel {
-        private final static int INVALID_LISTENER_KEY = 0;
-
-        private ChannelListener mChannelListener;
-
-        private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>();
-        private HashMap<Integer, Integer> mListenerMapCount = new HashMap<Integer, Integer>();
-        private Object mListenerMapLock = new Object();
-        private int mListenerKey = 0;
-
-        private List<ScanResult> mAnqpRequest = new LinkedList<ScanResult>();
-        private Object mAnqpRequestLock = new Object();
-
-        private AsyncChannel mAsyncChannel;
-        private PasspointHandler mHandler;
-        Context mContext;
-
-        Channel(Context context, Looper looper, ChannelListener l) {
-            mAsyncChannel = new AsyncChannel();
-            mHandler = new PasspointHandler(looper);
-            mChannelListener = l;
-            mContext = context;
-        }
-
-        private int putListener(Object listener) {
-            return putListener(listener, 1);
-        }
-
-        private int putListener(Object listener, int count) {
-            if (listener == null || count <= 0)
-                return INVALID_LISTENER_KEY;
-            int key;
-            synchronized (mListenerMapLock) {
-                do {
-                    key = mListenerKey++;
-                } while (key == INVALID_LISTENER_KEY);
-                mListenerMap.put(key, listener);
-                mListenerMapCount.put(key, count);
-            }
-            return key;
-        }
-
-        private Object peekListener(int key) {
-            Log.d(TAG, "peekListener() key=" + key);
-            if (key == INVALID_LISTENER_KEY)
-                return null;
-            synchronized (mListenerMapLock) {
-                return mListenerMap.get(key);
-            }
-        }
-
-
-        private Object getListener(int key, boolean forceRemove) {
-            Log.d(TAG, "getListener() key=" + key + " force=" + forceRemove);
-            if (key == INVALID_LISTENER_KEY)
-                return null;
-            synchronized (mListenerMapLock) {
-                if (!forceRemove) {
-                    int count = mListenerMapCount.get(key);
-                    Log.d(TAG, "count=" + count);
-                    mListenerMapCount.put(key, --count);
-                    if (count > 0)
-                        return null;
-                }
-                Log.d(TAG, "remove key");
-                mListenerMapCount.remove(key);
-                return mListenerMap.remove(key);
-            }
-        }
-
-        private void anqpRequestStart(ScanResult sr) {
-            Log.d(TAG, "anqpRequestStart sr.bssid=" + sr.BSSID);
-            synchronized (mAnqpRequestLock) {
-                mAnqpRequest.add(sr);
-            }
-        }
-
-        private void anqpRequestFinish(WifiPasspointInfo result) {
-            Log.d(TAG, "anqpRequestFinish pi.bssid=" + result.bssid);
-            synchronized (mAnqpRequestLock) {
-                for (ScanResult sr : mAnqpRequest)
-                    if (sr.BSSID.equals(result.bssid)) {
-                        Log.d(TAG, "find hit " + result.bssid);
-                        /* sr.passpoint = result; */
-                        mAnqpRequest.remove(sr);
-                        Log.d(TAG, "mAnqpRequest.len=" + mAnqpRequest.size());
-                        break;
-                    }
-            }
-        }
-
-        private void anqpRequestFinish(ScanResult sr) {
-            Log.d(TAG, "anqpRequestFinish sr.bssid=" + sr.BSSID);
-            synchronized (mAnqpRequestLock) {
-                for (ScanResult sr1 : mAnqpRequest)
-                    if (sr1.BSSID.equals(sr.BSSID)) {
-                        mAnqpRequest.remove(sr1);
-                        break;
-                    }
-            }
-        }
-
-        class PasspointHandler extends Handler {
-            PasspointHandler(Looper looper) {
-                super(looper);
-            }
-
-            @Override
-            public void handleMessage(Message message) {
-                Object listener = null;
-
-                switch (message.what) {
-                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                        if (mChannelListener != null) {
-                            mChannelListener.onChannelDisconnected();
-                            mChannelListener = null;
-                        }
-                        break;
-
-                    case REQUEST_ANQP_INFO_SUCCEEDED:
-                        WifiPasspointInfo result = (WifiPasspointInfo) message.obj;
-                        anqpRequestFinish(result);
-                        listener = getListener(message.arg2, false);
-                        if (listener != null) {
-                            ((ActionListener) listener).onSuccess();
-                        }
-                        break;
-
-                    case REQUEST_ANQP_INFO_FAILED:
-                        anqpRequestFinish((ScanResult) message.obj);
-                        listener = getListener(message.arg2, false);
-                        if (listener == null)
-                            getListener(message.arg2, true);
-                        if (listener != null) {
-                            ((ActionListener) listener).onFailure(message.arg1);
-                        }
-                        break;
-
-                    case START_OSU_SUCCEEDED:
-                        listener = getListener(message.arg2, true);
-                        if (listener != null) {
-                            ((OsuRemListener) listener).onSuccess();
-                        }
-                        break;
-
-                    case START_OSU_FAILED:
-                        listener = getListener(message.arg2, true);
-                        if (listener != null) {
-                            ((OsuRemListener) listener).onFailure(message.arg1);
-                        }
-                        break;
-
-                    case START_OSU_BROWSER:
-                        listener = peekListener(message.arg2);
-                        if (listener != null) {
-                            ParcelableString str = (ParcelableString) message.obj;
-                            if (str == null || str.string == null)
-                                ((OsuRemListener) listener).onBrowserDismiss();
-                            else
-                                ((OsuRemListener) listener).onBrowserLaunch(str.string);
-                        }
-                        break;
-
-                    default:
-                        Log.d(TAG, "Ignored " + message);
-                        break;
-                }
-            }
-        }
-
-    }
-
-    public static class ParcelableString implements Parcelable {
-        public String string;
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            out.writeString(string);
-        }
-
-        public static final Parcelable.Creator<ParcelableString> CREATOR =
-                new Parcelable.Creator<ParcelableString>() {
-                    @Override
-                    public ParcelableString createFromParcel(Parcel in) {
-                        ParcelableString ret = new ParcelableString();
-                        ret.string = in.readString();
-                        return ret;
-                    }
-                    @Override
-                    public ParcelableString[] newArray(int size) {
-                        return new ParcelableString[size];
-                    }
-        };
-    }
-
-    private static final int BASE = Protocol.BASE_WIFI_PASSPOINT_MANAGER;
-
-    public static final int REQUEST_ANQP_INFO                   = BASE + 1;
-    public static final int REQUEST_ANQP_INFO_FAILED            = BASE + 2;
-    public static final int REQUEST_ANQP_INFO_SUCCEEDED         = BASE + 3;
-    public static final int REQUEST_OSU_ICON                    = BASE + 4;
-    public static final int REQUEST_OSU_ICON_FAILED             = BASE + 5;
-    public static final int REQUEST_OSU_ICON_SUCCEEDED          = BASE + 6;
-    public static final int START_OSU                           = BASE + 7;
-    public static final int START_OSU_BROWSER                   = BASE + 8;
-    public static final int START_OSU_FAILED                    = BASE + 9;
-    public static final int START_OSU_SUCCEEDED                 = BASE + 10;
-
-    private Context mContext;
-    IWifiPasspointManager mService;
-
-    /**
-     * TODO: doc
-     * @param context
-     * @param service
-     */
-    public WifiPasspointManager(Context context, IWifiPasspointManager service) {
-        mContext = context;
-        mService = service;
-    }
-
-    /**
-     * Registers the application with the framework. This function must be the
-     * first to be called before any async passpoint operations are performed.
-     *
-     * @param srcContext is the context of the source
-     * @param srcLooper is the Looper on which the callbacks are receivied
-     * @param listener for callback at loss of framework communication. Can be
-     *            null.
-     * @return Channel instance that is necessary for performing any further
-     *         passpoint operations
-     *
-     */
-    public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
-        Messenger messenger = getMessenger();
-        if (messenger == null)
-            return null;
-
-        Channel c = new Channel(srcContext, srcLooper, listener);
-        if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
-                == AsyncChannel.STATUS_SUCCESSFUL) {
-            return c;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * STOPSHIP: temp solution, should use supplicant manager instead, check
-     * with b/13931972
-     */
-    public Messenger getMessenger() {
-        try {
-            return mService.getMessenger();
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    public int getPasspointState() {
-        try {
-            return mService.getPasspointState();
-        } catch (RemoteException e) {
-            return PASSPOINT_STATE_UNKNOWN;
-        }
-    }
-
-    public void requestAnqpInfo(Channel c, List<ScanResult> requested, int mask,
-            ActionListener listener) {
-        Log.d(TAG, "requestAnqpInfo start");
-        Log.d(TAG, "requested.size=" + requested.size());
-        checkChannel(c);
-        List<ScanResult> list = new ArrayList<ScanResult>();
-        for (ScanResult sr : requested)
-            if (sr.capabilities.contains("[HS20]")) {
-                list.add(sr);
-                c.anqpRequestStart(sr);
-                Log.d(TAG, "adding " + sr.BSSID);
-            }
-        int count = list.size();
-        Log.d(TAG, "after filter, count=" + count);
-        if (count == 0) {
-            if (DBG)
-                Log.d(TAG, "ANQP info request contains no HS20 APs, skipped");
-            listener.onSuccess();
-            return;
-        }
-        int key = c.putListener(listener, count);
-        for (ScanResult sr : list)
-            c.mAsyncChannel.sendMessage(REQUEST_ANQP_INFO, mask, key, sr);
-        Log.d(TAG, "requestAnqpInfo end");
-    }
-
-    public void requestOsuIcons(Channel c, List<WifiPasspointOsuProvider> requested,
-            int resolution, ActionListener listener) {
-    }
-
-    public List<WifiPasspointPolicy> requestCredentialMatch(List<ScanResult> requested) {
-        try {
-            return mService.requestCredentialMatch(requested);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Get a list of saved Passpoint credentials. Only those credentials owned
-     * by the caller will be returned.
-     *
-     * @return The list of credentials
-     */
-    public List<WifiPasspointCredential> getCredentials() {
-        try {
-            return mService.getCredentials();
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Add a new Passpoint credential.
-     *
-     * @param cred The credential to be added
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
-     */
-    public boolean addCredential(WifiPasspointCredential cred) {
-        try {
-            return mService.addCredential(cred);
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Update an existing Passpoint credential. Only system or the owner of this
-     * credential has the permission to do this.
-     *
-     * @param cred The credential to be updated
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
-     */
-    public boolean updateCredential(WifiPasspointCredential cred) {
-        try {
-            return mService.updateCredential(cred);
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Remove an existing Passpoint credential. Only system or the owner of this
-     * credential has the permission to do this.
-     *
-     * @param cred The credential to be removed
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
-     */
-    public boolean removeCredential(WifiPasspointCredential cred) {
-        try {
-            return mService.removeCredential(cred);
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-
-    public void startOsu(Channel c, WifiPasspointOsuProvider osu, OsuRemListener listener) {
-        Log.d(TAG, "startOsu start");
-        checkChannel(c);
-        int key = c.putListener(listener);
-        c.mAsyncChannel.sendMessage(START_OSU, 0, key, osu);
-        Log.d(TAG, "startOsu end");
-    }
-
-    public void startRemediation(Channel c, OsuRemListener listener) {
-    }
-
-    public void connect(WifiPasspointPolicy policy) {
-    }
-
-    private static void checkChannel(Channel c) {
-        if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
-    }
-}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl
deleted file mode 100644
index 088136f..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-parcelable WifiPasspointOsuProvider;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java
deleted file mode 100644
index b54b70c..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public class WifiPasspointOsuProvider implements Parcelable {
-
-    /** TODO: doc
-     * @hide
-     */
-    public static final int OSU_METHOD_UNKNOWN = -1;
-
-    /** TODO: doc
-     * @hide
-     */
-    public static final int OSU_METHOD_OMADM = 0;
-
-    /** TODO: doc
-     * @hide
-     */
-    public static final int OSU_METHOD_SOAP = 1;
-
-    /** TODO: doc */
-    public String ssid;
-
-    /** TODO: doc */
-    public String friendlyName;
-
-    /** TODO: doc
-     * @hide
-     */
-    public String serverUri;
-
-    /** TODO: doc
-     * @hide
-     */
-    public int osuMethod = OSU_METHOD_UNKNOWN;
-
-    /** TODO: doc */
-    public int iconWidth;
-
-    /** TODO: doc */
-    public int iconHeight;
-
-    /** TODO: doc */
-    public String iconType;
-
-    /** TODO: doc */
-    public String iconFileName;
-
-    /** TODO: doc */
-    public Object icon; // TODO: should change to image format
-
-    /** TODO: doc */
-    public String osuNai;
-
-    /** TODO: doc */
-    public String osuService;
-
-    /** default constructor @hide */
-    public WifiPasspointOsuProvider() {
-        // TODO
-    }
-
-    /** copy constructor @hide */
-    public WifiPasspointOsuProvider(WifiPasspointOsuProvider source) {
-        // TODO
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append("SSID: ").append("<").append(ssid).append(">");
-        if (friendlyName != null)
-            sb.append(" friendlyName: ").append("<").append(friendlyName).append(">");
-        if (serverUri != null)
-            sb.append(" serverUri: ").append("<").append(serverUri).append(">");
-        sb.append(" osuMethod: ").append("<").append(osuMethod).append(">");
-        if (iconFileName != null) {
-            sb.append(" icon: <").append(iconWidth).append("x")
-                    .append(iconHeight).append(" ")
-                    .append(iconType).append(" ")
-                    .append(iconFileName).append(">");
-        }
-        if (osuNai != null)
-            sb.append(" osuNai: ").append("<").append(osuNai).append(">");
-        if (osuService != null)
-            sb.append(" osuService: ").append("<").append(osuService).append(">");
-        return sb.toString();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(ssid);
-        out.writeString(friendlyName);
-        out.writeString(serverUri);
-        out.writeInt(osuMethod);
-        out.writeInt(iconWidth);
-        out.writeInt(iconHeight);
-        out.writeString(iconType);
-        out.writeString(iconFileName);
-        out.writeString(osuNai);
-        out.writeString(osuService);
-        // TODO: icon image?
-    }
-
-    public static final Parcelable.Creator<WifiPasspointOsuProvider> CREATOR =
-            new Parcelable.Creator<WifiPasspointOsuProvider>() {
-                @Override
-                public WifiPasspointOsuProvider createFromParcel(Parcel in) {
-                    WifiPasspointOsuProvider osu = new WifiPasspointOsuProvider();
-                    osu.ssid = in.readString();
-                    osu.friendlyName = in.readString();
-                    osu.serverUri = in.readString();
-                    osu.osuMethod = in.readInt();
-                    osu.iconWidth = in.readInt();
-                    osu.iconHeight = in.readInt();
-                    osu.iconType = in.readString();
-                    osu.iconFileName = in.readString();
-                    osu.osuNai = in.readString();
-                    osu.osuService = in.readString();
-                    return osu;
-                }
-
-                @Override
-                public WifiPasspointOsuProvider[] newArray(int size) {
-                    return new WifiPasspointOsuProvider[size];
-                }
-            };
-}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl
deleted file mode 100644
index 1d61da0..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-parcelable WifiPasspointPolicy;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java
deleted file mode 100644
index c08877e..0000000
--- a/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.passpoint;
-
-import android.net.wifi.WifiConfiguration;
-import android.os.Parcelable;
-import android.os.Parcel;
-import android.security.Credentials;
-import android.util.Log;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-
-/** @hide */
-public class WifiPasspointPolicy implements Parcelable {
-
-    private final static String TAG = "PasspointPolicy";
-
-    /** @hide */
-    public static final int HOME_SP = 0;
-
-    /** @hide */
-    public static final int ROAMING_PARTNER = 1;
-
-    /** @hide */
-    public static final int UNRESTRICTED = 2;
-
-    private String mName;
-    private int mCredentialPriority;
-    private int mRoamingPriority;
-    private String mBssid;
-    private String mSsid;
-    private WifiPasspointCredential mCredential;
-    private int mRestriction;// Permitted values are "HomeSP", "RoamingPartner", or "Unrestricted"
-    private boolean mIsHomeSp;
-
-    private final String INT_PRIVATE_KEY = "private_key";
-    private final String INT_PHASE2 = "phase2";
-    private final String INT_PASSWORD = "password";
-    private final String INT_IDENTITY = "identity";
-    private final String INT_EAP = "eap";
-    private final String INT_CLIENT_CERT = "client_cert";
-    private final String INT_CA_CERT = "ca_cert";
-    private final String INT_ANONYMOUS_IDENTITY = "anonymous_identity";
-    private final String INT_SIM_SLOT = "sim_slot";
-    private final String INT_ENTERPRISEFIELD_NAME ="android.net.wifi.WifiConfiguration$EnterpriseField";
-    private final String ISO8601DATEFORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
-    private final String ENTERPRISE_PHASE2_MSCHAPV2 = "auth=MSCHAPV2";
-    private final String ENTERPRISE_PHASE2_MSCHAP = "auth=MSCHAP";
-
-    /** @hide */
-    public WifiPasspointPolicy(String name, String ssid,
-            String bssid, WifiPasspointCredential pc,
-            int restriction, boolean ishomesp) {
-        mName = name;
-        if (pc != null) {
-            mCredentialPriority = pc.getPriority();
-        }
-        //PerProviderSubscription/<X+>/Policy/PreferredRoamingPartnerList/<X+>/Priority
-        mRoamingPriority = 128; //default priority value of 128
-        mSsid = ssid;
-        mCredential = pc;
-        mBssid = bssid;
-        mRestriction = restriction;
-        mIsHomeSp = ishomesp;
-    }
-
-    public String getSsid() {
-        return mSsid;
-    }
-
-    /** @hide */
-    public void setBssid(String bssid) {
-        mBssid = bssid;
-    }
-
-    public String getBssid() {
-        return mBssid;
-    }
-
-    /** @hide */
-    public void setRestriction(int r) {
-        mRestriction = r;
-    }
-
-    /** @hide */
-    public int getRestriction() {
-        return mRestriction;
-    }
-
-    /** @hide */
-    public void setHomeSp(boolean b) {
-        mIsHomeSp = b;
-    }
-
-    /** @hide */
-    public boolean isHomeSp() {
-        return mIsHomeSp;
-    }
-
-    /** @hide */
-    public void setCredential(WifiPasspointCredential newCredential) {
-        mCredential = newCredential;
-    }
-
-    public WifiPasspointCredential getCredential() {
-        // TODO: return a copy
-        return mCredential;
-    }
-
-    /** @hide */
-    public void setCredentialPriority(int priority) {
-        mCredentialPriority = priority;
-    }
-
-    /** @hide */
-    public void setRoamingPriority(int priority) {
-        mRoamingPriority = priority;
-    }
-
-    public int getCredentialPriority() {
-        return mCredentialPriority;
-    }
-
-    public int getRoamingPriority() {
-        return mRoamingPriority;
-    }
-
-    public WifiConfiguration createWifiConfiguration() {
-        WifiConfiguration wfg = new WifiConfiguration();
-        if (mBssid != null) {
-            Log.d(TAG, "create bssid:" + mBssid);
-            wfg.BSSID = mBssid;
-        }
-
-        if (mSsid != null) {
-            Log.d(TAG, "create ssid:" + mSsid);
-            wfg.SSID = mSsid;
-        }
-        //TODO: 1. add pmf configuration
-        //      2. add ocsp configuration
-        //      3. add eap-sim configuration
-        /*Key management*/
-        wfg.status = WifiConfiguration.Status.ENABLED;
-        wfg.allowedKeyManagement.clear();
-        wfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
-        wfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
-
-        /*Group Ciphers*/
-        wfg.allowedGroupCiphers.clear();
-        wfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
-        wfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
-
-        /*Protocols*/
-        wfg.allowedProtocols.clear();
-        wfg.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-        wfg.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
-
-        Class[] enterpriseFieldArray  = WifiConfiguration.class.getClasses();
-        Class<?> enterpriseFieldClass = null;
-
-
-        for(Class<?> myClass : enterpriseFieldArray) {
-            if(myClass.getName().equals(INT_ENTERPRISEFIELD_NAME)) {
-                enterpriseFieldClass = myClass;
-                break;
-            }
-        }
-        Log.d(TAG, "class chosen " + enterpriseFieldClass.getName() );
-
-
-        Field anonymousId = null, caCert = null, clientCert = null,
-              eap = null, identity = null, password = null,
-              phase2 = null, privateKey =  null;
-
-        Field[] fields = WifiConfiguration.class.getFields();
-
-
-        for (Field tempField : fields) {
-            if (tempField.getName().trim().equals(INT_ANONYMOUS_IDENTITY)) {
-                anonymousId = tempField;
-                Log.d(TAG, "field " + anonymousId.getName() );
-            } else if (tempField.getName().trim().equals(INT_CA_CERT)) {
-                caCert = tempField;
-            } else if (tempField.getName().trim().equals(INT_CLIENT_CERT)) {
-                clientCert = tempField;
-                Log.d(TAG, "field " + clientCert.getName() );
-            } else if (tempField.getName().trim().equals(INT_EAP)) {
-                eap = tempField;
-                Log.d(TAG, "field " + eap.getName() );
-            } else if (tempField.getName().trim().equals(INT_IDENTITY)) {
-                identity = tempField;
-                Log.d(TAG, "field " + identity.getName() );
-            } else if (tempField.getName().trim().equals(INT_PASSWORD)) {
-                password = tempField;
-                Log.d(TAG, "field " + password.getName() );
-            } else if (tempField.getName().trim().equals(INT_PHASE2)) {
-                phase2 = tempField;
-                Log.d(TAG, "field " + phase2.getName() );
-
-            } else if (tempField.getName().trim().equals(INT_PRIVATE_KEY)) {
-                privateKey = tempField;
-            }
-        }
-
-
-        Method setValue = null;
-
-        for(Method m: enterpriseFieldClass.getMethods()) {
-            if(m.getName().trim().equals("setValue")) {
-                Log.d(TAG, "method " + m.getName() );
-                setValue = m;
-                break;
-            }
-        }
-
-        try {
-            // EAP
-            String eapmethod = mCredential.getType();
-            Log.d(TAG, "eapmethod:" + eapmethod);
-            setValue.invoke(eap.get(wfg), eapmethod);
-
-            // Username, password, EAP Phase 2
-            if ("TTLS".equals(eapmethod)) {
-                setValue.invoke(phase2.get(wfg), ENTERPRISE_PHASE2_MSCHAPV2);
-                setValue.invoke(identity.get(wfg), mCredential.getUserName());
-                setValue.invoke(password.get(wfg), mCredential.getPassword());
-                setValue.invoke(anonymousId.get(wfg), "anonymous@" + mCredential.getRealm());
-            }
-
-            // EAP CA Certificate
-            String cacertificate = null;
-            String rootCA = mCredential.getCaRootCertPath();
-            if (rootCA == null){
-                cacertificate = null;
-            } else {
-                cacertificate = "keystore://" + Credentials.WIFI + "HS20" + Credentials.CA_CERTIFICATE + rootCA;
-            }
-            Log.d(TAG, "cacertificate:" + cacertificate);
-            setValue.invoke(caCert.get(wfg), cacertificate);
-
-            //User certificate
-            if ("TLS".equals(eapmethod)) {
-                String usercertificate = null;
-                String privatekey = null;
-                String clientCertPath = mCredential.getClientCertPath();
-                if (clientCertPath != null){
-                    privatekey = "keystore://" + Credentials.WIFI + "HS20" + Credentials.USER_PRIVATE_KEY + clientCertPath;
-                    usercertificate = "keystore://" + Credentials.WIFI + "HS20" + Credentials.USER_CERTIFICATE + clientCertPath;
-                }
-                Log.d(TAG, "privatekey:" + privatekey);
-                Log.d(TAG, "usercertificate:" + usercertificate);
-                if (privatekey != null && usercertificate != null) {
-                    setValue.invoke(privateKey.get(wfg), privatekey);
-                    setValue.invoke(clientCert.get(wfg), usercertificate);
-                }
-            }
-        } catch (Exception e) {
-            Log.d(TAG, "createWifiConfiguration err:" + e);
-        }
-
-        return wfg;
-    }
-
-    /** {@inheritDoc} @hide */
-    public int compareTo(WifiPasspointPolicy another) {
-        Log.d(TAG, "this:" + this);
-        Log.d(TAG, "another:" + another);
-
-        if (another == null) {
-            return -1;
-        } else if (this.mIsHomeSp == true && another.isHomeSp() == false) {
-            //home sp priority is higher then roaming
-            Log.d(TAG, "compare HomeSP  first, this is HomeSP, another isn't");
-            return -1;
-        } else if ((this.mIsHomeSp == true && another.isHomeSp() == true)) {
-            Log.d(TAG, "both HomeSP");
-            //if both home sp, compare credential priority
-            if (this.mCredentialPriority < another.getCredentialPriority()) {
-                Log.d(TAG, "this priority is higher");
-                return -1;
-            } else if (this.mCredentialPriority == another.getCredentialPriority()) {
-                Log.d(TAG, "both priorities equal");
-                //if priority still the same, compare name(ssid)
-                if (this.mName.compareTo(another.mName) != 0) {
-                    Log.d(TAG, "compare mName return:" + this.mName.compareTo(another.mName));
-                    return this.mName.compareTo(another.mName);
-                }
-                /**
-                 *if name still the same, compare credential
-                 *the device may has two more credentials(TLS,SIM..etc)
-                 *it can associate to one AP(same ssid). so we should compare by credential
-                 */
-                if (this.mCredential != null && another.mCredential != null) {
-                    if (this.mCredential.compareTo(another.mCredential) != 0) {
-                        Log.d(TAG,
-                                "compare mCredential return:" + this.mName.compareTo(another.mName));
-                        return this.mCredential.compareTo(another.mCredential);
-                    }
-                }
-            } else {
-                return 1;
-            }
-        } else if ((this.mIsHomeSp == false && another.isHomeSp() == false)) {
-            Log.d(TAG, "both RoamingSp");
-            //if both roaming sp, compare roaming priority(preferredRoamingPartnerList/<X+>/priority)
-            if (this.mRoamingPriority < another.getRoamingPriority()) {
-                Log.d(TAG, "this priority is higher");
-                return -1;
-            } else if (this.mRoamingPriority == another.getRoamingPriority()) {//priority equals, compare name
-                Log.d(TAG, "both priorities equal");
-                //if priority still the same, compare name(ssid)
-                if (this.mName.compareTo(another.mName) != 0) {
-                    Log.d(TAG, "compare mName return:" + this.mName.compareTo(another.mName));
-                    return this.mName.compareTo(another.mName);
-                }
-                //if name still the same, compare credential
-                if (this.mCredential != null && another.mCredential != null) {
-                    if (this.mCredential.compareTo(another.mCredential) != 0) {
-                        Log.d(TAG,
-                                "compare mCredential return:"
-                                        + this.mCredential.compareTo(another.mCredential));
-                        return this.mCredential.compareTo(another.mCredential);
-                    }
-                }
-            } else {
-                return 1;
-            }
-        }
-
-        Log.d(TAG, "both policies equal");
-        return 0;
-    }
-
-    @Override
-    /** @hide */
-    public String toString() {
-        return "PasspointPolicy: name=" + mName + " CredentialPriority=" + mCredentialPriority +
-                " mRoamingPriority" + mRoamingPriority +
-                " ssid=" + mSsid + " restriction=" + mRestriction +
-                " ishomesp=" + mIsHomeSp + " Credential=" + mCredential;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        // TODO
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public static final Creator<WifiPasspointPolicy> CREATOR =
-            new Creator<WifiPasspointPolicy>() {
-                @Override
-                public WifiPasspointPolicy createFromParcel(Parcel in) {
-                    return null;
-                }
-
-                @Override
-                public WifiPasspointPolicy[] newArray(int size) {
-                    return new WifiPasspointPolicy[size];
-                }
-            };
-}